According to The Rust Programming Language:
Since scopes always nest, another way to say this is that the generic lifetime
'a
will get the concrete lifetime equal to the smaller of the lifetimes ofx
andy
.
fn main() {
let x = "abcd";
let result;
{
let y = "qwerty";
result = longest(x, y);
}
println!("The longest string is {} ", result);
}
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() {
x
} else {
y
}
}
In the main function, "the smaller of the lifetimes of x and y" is the nested scope. This should be the lifetime of the value in result
as well, but the result contains the correct value from outside of that nested scope.
Why does this code work correctly?
That's only true when talking about lifetimes derived from borrowing local variables. In this case, the relevant lifetime is the lifetime of the string data, which for string literals is 'static
. In other words, the &str
s are pointing to data stored elsewhere (in the static data segment, specifically), so they don't interact with stack lifetimes at all.
If we change the example slightly, we can induce the behaviour you're expecting:
fn main() {
let x = "abcd";
let result;
{
let y = "qwerty";
result = longest(&x, &y);
}
println!("The longest string is {} ", result);
}
fn longest<'a>(x: &'a &'static str, y: &'a &'static str) -> &'a &'static str {
if x.len() > y.len() {
x
} else {
y
}
}
Which fails to compile with:
error[E0597]: `y` does not live long enough
--> src/main.rs:6:35
|
6 | result = longest(&x, &y);
| ^ borrowed value does not live long enough
7 | }
| - `y` dropped here while still borrowed
...
10 | }
| - borrowed value needs to live until here
This fails because now we're talking about borrows into the stack.
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