Context: I just wanted to understand a little bit more about lifetimes and template types and came up with an easy function family which does not make much sense, I was not able to create a template from.
First the function (one for non reference type, and one for the reference type) without a template
fn first_string(first: String, _second: String) -> String {
first
}
fn first_string_ref<'a>(
first: &'a String,
_second: &String,
) -> &'a String {
first
}
The function(s) do not make much sense and are only used for learning. They seem to look quite equal for the version using the String
and the &String
.
I tried to following function to make a template from both:
fn first_template<T>(first: T, _second: T) -> T {
first
}
but this fails with the following test code:
fn test_first_template() {
let first = "first".to_owned();
print!("first_string: {first}, ");
let result = {
let second = "second".to_owned();
print!("{second} is ");
first_template(&first, &second)
};
println!("{result}");
}
The error message is completly understood and can be fixed, if I add another template type U for the second parameter. However the following code shall not compile (types of the first and second paramter shall be equal despite of their lifetime):
fn test_first_template_not_compile() {
let first = "hallo".to_owned();
print!("first_string: {first}, ");
let result = {
let second = vec![0];
print!("{second:?} is ");
first_template(&first, &second)
};
println!("{result}");
}
So here are my questions (related to stable rust):
- How to change
first_template
, so that it fulfills all the restrictions and compilestest_first_template
? - If it is not possible with one template function: Is it possible with two functions (one for reference Arguments and one for move arguments? Here we have another restriction: The reference function shall not compile, if not reference arguments are given (I think this is easy), the non reference function shall not compile if reference arguments are given to it.