The lifetime of &str really confuses me

fn a() -> &'static str {
    let v1 = "123";
    //let v1 = String::from("123");
    &v1
}

fn main() {

    let foo = a();
    println!("{}", foo);

    let bar = {
        let v2 = "123";
        &v2
    };
    println!("{}", bar);

}

As the code above, the value foo can be printed without any error while bar cannot be printed because v2 is a local variable and doesn't live long enough.
v1 is also a local variable, why foo can be printed?
Lifetime annotation doesn't change the lifetime of variables, or I have some misunderstanding?

1 Like

let bar: &'static str = ... makes your code compileable :wink:

I think your question is answered here:
https://stackoverflow.com/questions/50345139/why-can-i-return-a-reference-to-a-local-literal-but-not-a-variable

1 Like

oh thanks, this helps a lot.

String literals (&'static str) are a special case of references that live forever, because they're hardcoded into your program and they will never be freed.

All other references are temporary borrows, because they borrow from String or some other type that will be freed.

3 Likes

Let it be noted that there is an implicit Deref taking place here (&T implements Deref<Target = T>):

fn a () -> &'static str
{
    let v1 = "123"; // string literal == borrow of a static string slice
    // &v1 -> &*v1 by deref coercion
    &*v1 // deref leads to a reborrow of the static string slice, hence able to oulive local v1
}

fn main ()
{
    let foo = a();
    println!("{}", foo);

    let bar = {
        let v2 = "123";
        &v2 // no type annotation so no deref coercion: it does borrow from local v2
    }; // type &&str
    // error
    println!("{}", bar);
}
9 Likes

now I understand why it works so, thanks a lot!

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.