11
votes

I have a bit of code that I'm fighting with. It's a little helper function that should return a Vec<&str> to the calling function. I can't seem to get the lifetime right, though.

Here is the code snippet:

fn take_symbol<'a>(ch: &'a str, current: &'a mut String) -> &'a mut TokenList<'a> {
    let out = TokenList::<'a>::new();

    out.push(current.as_str());
    out.push(ch);

    *current = String::new();

    &mut out
}

The compiler is telling me: error: 'out' does not live long enough and that the reference must be valid for the lifetime of 'a, but it looks to me like it is defined for 'a.

I have also tried changing it to:

let out = &mut TokenList::<'a>::new();

which doesn't change any of the error messages. Or:

let out = &'a mut TokenList::<'a>::new();

which the compiler doesn't like at all.

How do I define out to have a lifetime of 'a?

For further details, here is my definition of TokenList:

pub type Token<'a> = &'a str;
pub type TokenList<'a> = Vec<Token<'a>>;
1
In short, lifetimes only describe how long something lives, never influence how long it lives.user395760
Too bad. That would be a nice feature. Thanks!wmaxlees

1 Answers

11
votes

The lifetime of out is not 'a, since out is destroyed at the end of the function. Rust will not allow you to return a reference to it (it would allow accessing freed memory!).

Try changing your function to the following:

fn take_symbol<'a>(ch: &'a str, current: &'a mut String) -> TokenList<'a> {
    let out = TokenList::<'a>::new();

    out.push(current.as_str());
    out.push(ch);

    *current = String::new();

    out
}

This way you will pass the ownership of out to the caller and it will live long enough.