liveBook · Manning

Lifetime

As explained in Learn Rust in a Month of Lunches

A variable lifetime is the interval during which a variable binding is valid and accessible.

A lifetime is how long a variable or reference lives. A variable declared inside a `{}` code block lives until that block ends. Afterward, its name is no longer available. section 1.6

fn main() {
    {
        let my_number = 8;                      #1
    }
    println!("Hello, number {}", my_number);    #2
}

Here, `my_number` is declared inside the inner block. Trying to print it after that block ends causes an error. section 1.7

Need the result outside the block? Make the block return a value and assign that value to an outer variable. The inner variable still ends with its block. Leave off the final semicolon when returning the value; adding it makes the block return `()` instead. section 1.7

Lifetimes matter especially for references. A reference points to data elsewhere, so it cannot remain usable after that data is gone. Rust usually works out lifetimes without annotations, but sometimes it needs extra information. section 10.2 section 10.0

Returning a string reference

A function cannot return `&my_string` when `my_string` is a local `String`: the string ends when the function does. It can return the owned `String` instead. A string literal is different: it has the program-long `'static` lifetime, so a function returning one can declare `-> &'static str`. That declaration describes what the function returns; it does not make a short-lived value live longer. section 10.1 section 10.2.1

error[E0106]: missing lifetime specifier
 --> src\main.rs:6:21
  |
6 | fn returns_str() -> &str {
  |                     ^ expected named lifetime parameter
  |
  = help: this function's return type contains a borrowed value, but there
  is no value for it to be borrowed from
help: consider using the `'static` lifetime
  |
6 | fn returns_str() -> &'static str {
  |                     ^^^^^^^^

The missing-lifetime error explains why a bare `-> &str` needs more information here and suggests `'static` for a returned string literal. section 10.2.1

A struct holding a reference needs a lifetime too. In `struct City<'a> { name: &'a str, ... }`, `'a` says the referenced name must last at least as long as the struct needs it. Choosing `&'static str` instead restricts that field to program-long data; it will not accept a reference to an ordinary `String` just because that string lasts long enough for one use. section 10.2.2

#[derive(Debug)]
struct City<'a> {        #1
    name: &'a str,       #2
    date_founded: u32,
}
 
fn main() {
    let city_names = vec!["Ichinomiya".to_string(), "Kurume".to_string()];
 
    let my_city = City {
        name: &city_names[0],
        date_founded: 1921,
    };
 
    println!("{} was founded in {}", my_city.name, my_city.date_founded);
}

The named lifetime lets this struct borrow a name from a `String` while that string remains available. section 10.2.2

You may also see `'_`, the anonymous lifetime, in an `impl` for a struct containing references. It indicates that a lifetime is involved without repeating its name. When the compiler asks for a lifetime, use the error to identify which reference needs one—an annotation expresses a requirement, not a way to extend the data’s life. section 10.2.3 section 10.2.1

How Learn Rust in a Month of Lunches covers it

How deep it goes
Develops block scope, function returns, and named and anonymous annotations through examples and compiler errors, without explaining compiler internals.
Examples
Uses an out-of-scope number, a returned string literal, and a struct borrowing a city name.
What it assumes
Introduces lifetimes from code blocks and variable declarations, then assumes familiarity with references, `String`, `&str`, and structs.
What you can do after
Diagnose/debug with it by reading lifetime errors and choosing owned returns, `'static` literals, or named lifetimes as appropriate.
How it connects
Connects lifetimes to code blocks, references, string literals, borrowed strings, structs, and generics.

Also explained in

Compare how 8 books explain lifetime →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Learn Rust in a Month of Lunches. The section links point to the parts of the book it draws on.