thecodex.expert · The Codex Family of Knowledge
Rust

Lifetimes

Lifetime annotations don’t make a value live any longer or shorter — they just describe an existing relationship so the compiler can verify it, and vanish completely once compilation is done.

Rust 1.96 Compile-time only Last verified:
Canonical Definition

A lifetime is the span of code for which a reference remains valid. Most of the time, lifetimes are inferred automatically and never need to be written. Explicit lifetime annotations (written 'a) become necessary when the compiler cannot work out on its own how the lifetimes of several references relate — most commonly, a function that returns a reference derived from one of its parameters. The annotation is purely a description for the compiler to check; it has zero effect on how long anything actually lives at runtime.

The problem lifetimes solve

Without an annotation, this function would not compile: given two references, the compiler cannot tell on its own whether the returned reference's validity depends on the first parameter, the second, or both.

Rustthe_problem.rs
// fn longest(x: &str, y: &str) -> &str {   // COMPILE ERROR: missing lifetime specifier
//     if x.len() > y.len() { x } else { y }
// }

Annotating the relationship

The annotation <'a> says: the returned reference is valid for exactly as long as BOTH x and y are valid — it's a constraint the compiler then checks at every call site, rejecting any call where the returned reference could outlive the data it points to.

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

let s1 = String::from("long string");
let result;
{
    let s2 = String::from("short");
    result = longest(s1.as_str(), s2.as_str());
    println!("{}", result);   // fine — s2 still alive here
}
// println!("{}", result);    // would be a COMPILE ERROR here — s2 already dropped

Lifetime elision: most of the time, you write nothing

The compiler applies a small set of well-defined rules (lifetime elision) that correctly infer lifetimes for the overwhelming majority of functions — a single-reference-parameter function, or a method taking &self, essentially never needs an explicit annotation. Explicit lifetimes only surface for genuinely ambiguous cases like longest above, where multiple reference parameters could plausibly relate to the return value.

Sources

1
The Rust Project. The Rust Programming Language, "Validating References with Lifetimes", doc.rust-lang.org/book/ch10-03.