I'm just starting to learn Rust, and I tried typing down the following functions.
fn longest<'a>(a: &'a str, b: &'a str) -> &'a str{
if a.len() > b.len() {
a
} else {
b
}
}
fn main() {
let a = "hi";
let c: &str;
{
let b = "nooooo";
c = longest(a, b);
}
print!("{c}");
}
Why does the code compile and print "nooooo"? Shouldn't b
's lifetime end in the inner scope, why can we still use c
?
String literals has a 'static
lifetime. It doesn't matter that b
is dropped at the end of the inner scope, because value "nooooo"
lives for the lifetime of the program (as it is stored in the binary itself). Problem will occur, when you for example allocate String
on heap and then take a reference to it, which will have a shorter lifetime:
fn longest<'a>(a: &'a str, b: &'a str) -> &'a str{
if a.len() > b.len() {
a
} else {
b
}
}
fn main() {
let a = "hi";
let c: &str;
{
let b = String::from("nooooo");
c = longest(a, &b);
}
print!("{c}");
}
This will fail to compile with the following error:
error[E0597]: `b` does not live long enough
--> src/main.rs:14:24
|
13 | let b = String::from("nooooo");
| - binding `b` declared here
14 | c = longest(a, &b);
| ^^ borrowed value does not live long enough
15 | }
| - `b` dropped here while still borrowed
16 | print!("{c}");
| --- borrow later used here