For the most part, in simple functions, lifetimes are completely implied. However, not exactly in the way you would expect. If the result of a function returns something with a lifetime, and the function takes in something with a lifetime, the two lifetimes are implied to be the same.
For example, this works without any lifetime specifiers:
fn convert_to_option(x: &str) -> Option<&str> {
Some(x)
}
I think the problem you were having was with requiring an output of a function to a 'static
lifetime, when the input to that function isn't guaranteed to have a 'static
lifetime. 'static
is a lifetime which lasts for the entire program, and is guaranteed to not ever be "dropped" (forgotten from memory), but most references are from values created on the stack, and thus will be dropped when the function they were created in ends.
@sellibitze I think you are slightly confused because of dereferencing coercions.
If you have a variable which the compiler knows is &str
, and you have a str reference with any number of &
s, the compiler will automatically insert enough *
dereferences to get you the variable type you want.
For example, this function works perfectly fine:
fn make_a_vec(thing: &'static str) -> Vec<&'static str> {
vec![&thing, &thing, &thing]
}
Or, to demonstrate using let
statements:
fn main() {
let a: &str = "hi"; // this is an &str
let b = &&a; // this is an &&&str
let c: &str = &b; // however, due to deref coercions, this is simply an `&str` again now.
let d = &**b; // d is also an &str now. This statement is exactly equivalent to `let c: &str = &b;` in what the compiler automatically inserts.
}
As long as the type is exactly known, using &
to turn an &&str
into an &str
works perfectly fine. I think the issue before was having the input str bound to an arbitrary lifetime, and the output str being required to be 'static
.