Lifetime specifier

fn main()
{
    let long;
    let str1 = "12323".to_string();
    {
        let str2 = "asdhuisdihuds".to_string();
        long = longest(&str1, &str2);
        
        println!("{}", long);
    }

    
}

fn longest(x: &str, y: &str) -> &str // Error over here
{
    if x.len() > y.len()
    {
        x
    }
    else
    {
        y
    }
}

I understand I have an error here and I can fix this by doing this:

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

But I don't quite get why do I have to specify its lifetime for &str?

The answer is given just after where this example appears in the Book.

The help text reveals that the return type needs a generic lifetime parameter on it because Rust can’t tell whether the reference being returned refers to x or y . Actually, we don’t know either, because the if block in the body of this function returns a reference to x and the else block returns a reference to y !

When we’re defining this function, we don’t know the concrete values that will be passed into this function, so we don’t know whether the if case or the else case will execute. We also don’t know the concrete lifetimes of the references that will be passed in, so we can’t look at the scopes as we did in Listings 10-18 and 10-19 to determine whether the reference we return will always be valid. The borrow checker can’t determine this either, because it doesn’t know how the lifetimes of x and y relate to the lifetime of the return value. To fix this error, we’ll add generic lifetime parameters that define the relationship between the references so the borrow checker can perform its analysis.

1 Like