Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Expanding Rust Lifetime

Tags:

rust

lifetime

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>>;
like image 988
wmaxlees Avatar asked Jul 06 '15 18:07

wmaxlees


People also ask

How do lifetimes work in Rust?

Lifetimes are what the Rust compiler uses to keep track of how long references are valid for. Checking references is one of the borrow checker's main responsibilities. Lifetimes help the borrow checker ensure that you never have invalid references.

What is a lifetime parameter Rust?

A generic lifetime parameter imposes a lifetime constraint on the reference(s) and the return value(s) of a function. While compiling the code, a generic lifetime is substituted for a concrete lifetime, which is equal to the smaller of the passed references' lifetimes.

Why are lifetimes needed in Rust?

Rather than ensuring that a type has the behavior we want, lifetimes ensure that references are valid as long as we need them to be. One detail we didn't discuss in the “References and Borrowing” section in Chapter 4 is that every reference in Rust has a lifetime, which is the scope for which that reference is valid.

What is static lifetime Rust?

A static is never "inlined" at the usage site, and all references to it refer to the same memory location. Static items have the static lifetime, which outlives all other lifetimes in a Rust program. Static items may be placed in read-only memory if the type is not interior mutable.


1 Answers

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.

like image 87
aochagavia Avatar answered Oct 21 '22 23:10

aochagavia