Lifetime simple question

I was reading about lifetimes in Rust book.

I was playing around with that and I see the next code compiles and works but I don't understand why since s2 in main has a lifetime shorter than result.

fn longest<'a>(s1: &'a str, s2: &'a str) -> &'a str {
    if s1.len() > s2.len() {
        s1
    } else {
        s2
    }
}

fn main() {
    let result;
    let s1 = String::from("ab");
    {
        let s2 = "xyz";
        result = longest(s1.as_str(), s2);
    }

    println!("{result}!");
}

Why is this happening?

Thanks!

Is it because s2 has a static lifetime?

"xyz" is hard coded,result point to it's address,that's valid

// because of this
        let result;
        
        let s2;
        let s1 = String::from("ab");
        {
            s2 = "xyz";
            result = longest(s1.as_str(), s2);
        }
        println!("{result}!");

for this, it's wrong

fn longest<'a>(s1: &'a String, s2: &'a String) -> &'a String {
            if s1.len() > s2.len() {
                s1
            } else {
                s2
            }
        }
        // because of this
        let result;

        let s1 = String::from("ab");
        {
            let s2 = String::from("xyz");
            // `s2` does not live long enough
            result = longest(&s1, &s2);
        }
        println!("{result}!");
1 Like

s2 doesn't hold the string itself, it only holds a reference with 'static lifetime (the longest possible lifetime, which is valid for the whole program duration) to some string hardcoded in the executable. This is just how string literals are implemented. If you instead defined s2 as String::from("xyz") then it wouldn't have worked.

2 Likes

This compiles down to a reference to an immutable global variable. The global variable is valid forever, so it's still valid at the end of main.

1 Like