While reading Chapter 12.4 of the Rust Book, I stumbled upon this function:
pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
vec![]
}
I understand why the code doesn't compile without the explicit lifetime annotation for the contents
argument and the return value - the lifetime elision rules do not apply for functions with at least two borrowed arguments.
But I'm curious what's the implicit lifetime annotation for the query
argument. I could think of two scenarios:
// Scenario 1
pub fn search<'a>(query: &'a str, contents: &'a str) -> Vec<&'a str> {
vec![]
}
// Scenario 2
pub fn search<'a, 'b>(query: &'b str, contents: &'a str) -> Vec<&'a str> {
vec![]
}
Both scenarios compile, so query
gets either lifetime 'a
or 'b
. Which one is correct?
From the rustonomicon
, under lifetime elision:
Each elided lifetime in input position becomes a distinct lifetime parameter.
You can try assigning the function to a wrong type. Compiler will tell you the correct type of the function:
let x: () = search;
Playground
Result:
error[E0308]: mismatched types
--> src/main.rs:6:17
|
6 | let x: () = search;
| -- ^^^^^^ expected `()`, found fn item
| |
| expected due to this
|
= note: expected unit type `()`
found fn item `for<'r, 'a> fn(&'r str, &'a str) -> Vec<&'a str> {search}`
So, type of your function is:
for<'r, 'a> fn(&'r str, &'a str) -> Vec<&'a str> {search}
Also, if query
also had lifetime 'a
, you should be able to do this:
pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
vec![query]
}
But this fails to compile because query
's lifetime is not 'a
.
Playground
One way to think of it is that we're not 'giving' a lifetime with lifetime annotations, but describing how the lifetime of your return value relates to the lifetimes of your inputs.
Lifetimes already exist, but annotations let us set relations between them. As you never relate the lifetime of query
to anything else in situation 2, we shouldn't really need to name it. Intuitively this makes sense as the most common case and the one that the compiler should (does) infer if you make no annotation on query
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With