Difference between &str and as_str()


#1

Hi
I’m following the examples of book V2 in chapter 10 and i’m trying to implement the longest function sample with lifetime annotation.
Here the example
fn longest<'a>(s1:&'a str,s2:&'a str) ->&'a str {
if s1.len() > s2.len() {
s1
} else {
s2
}
}

fn main() {
let s1=String::from(“long string is long”);
let result;
{
let s2=" xxvx";
result= longest(s1.as_str(),s2);
}
println!(“result {}”,result);

let result1;
{
let s3=String::from(“xxxx1111”); // DO NOT WORK
result1= longest(s1.as_str(),s3.as_str()); // DO NOT WORK

// let s3=“xxxx”; // WORK
// result1= longest(s1.as_str(),s3); // WORK
}
println!(“result {}”,result1);

}

Using String and your function as_str() the error is the same reported in book, when I use a &str all work fine.
Why the “error[E0597]: s3 does not live long enough” is present only with a &str returned by as_str()?
What is the difference between a function that retry a &str like as_str() and a simple pointer to str?

Thank Alex


#2

Please, wrap your code between two lines containing 3 ` (grave accent symbol) to keep indentation and improve readability

About your question, the problem is, as the compiler error suggests, the lifetime.
A String is allocated in the heap, so the lifetime of the &str contained inside (that is returned by the as_str() method provided by the standard library) is the one of the container, that is dropped at the end of the defined block while result1 has still a pointer to its content.
The string literal (&str) instead is in your code and is valid for the static lifetime, i.e. for the whole duration of your program


#3

Hi,
Thanks for suggestions, i will use the grave accent symbol the next time.
I suppose that &str is always static but i’m not sure; I find another info to understand in “Rust by example” at point 15.4.7 "When static_string goes out of scope, the reference can no longer be used, but the data remains in the binary. "
Alex


#4

Not quite, a simple "foo" is a &'static str, but if you borrow a &str from a String (e.g. s3.as_str() in your example), the &str will get a lifetime that is shorter than the liftetime of the String.