Following code doesn't compile as told in Listing 10-24.
fn main() {
let string1 = String::from("long string is long");
let result;
{
let string2 = String::from("xyz");
result = longest(string1.as_str(), string2.as_str());
}
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
}
}
But changing line 5 and 6 to following, compiles and works fine.
let string2 = "xyz";
result = longest(string1.as_str(), string2);
Though, string2
is out of scope now, the code still compiles and works fine. Through some experimentation, found out that when we're assigning String
to string2
, result
has the reference of same string.
But when we assign &str
to string2
, result
doesn't point to the same string.
I though maybe &str
might be implementing Copy
trait under the hood, but didn't find that in Docs. Also, I tried same setup with i32
(not &i32
) without lifetime annotation, it worked as it implements Copy
trait. But &str
doesn't work without lifetime annotations, though behave like they implement Copy
trait by being available after scope has ended.
Could somebody please explain, what exactly is happening here?