GGistDev

Lifetimes in Rust

Lifetimes describe the scope during which a reference is valid. The compiler uses lifetimes to prevent dangling references.

Elision rules (implicit lifetimes)

In many simple cases, Rust infers lifetimes so you don’t need to write them.

fn len(s: &str) -> usize { s.len() }               // input ties to output implicitly
fn first<'a>(s: &'a str) -> &'a str { &s[..1] }    // explicit equivalent

Elision rules tie output lifetimes to input references when unambiguous.

Explicit lifetimes

Add lifetime parameters when the compiler needs help relating inputs/outputs.

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

Structs with references

Structs holding references must name lifetimes.

struct Slice<'a> { data: &'a [u8] }
impl<'a> Slice<'a> {
    fn first(&self) -> Option<&'a u8> { self.data.first() }
}

Method receivers

&self and &mut self carry the struct’s lifetime implicitly.

'static lifetime

'static references live for the entire program (e.g., string literals). Avoid overusing 'static in APIs; it’s very restrictive.

let s: &'static str = "literal";

Lifetime bounds

Constrain generics with lifetime relationships.

fn foo<'a, T: 'a>(t: &'a T) { /* T outlives 'a */ }

Summary

  • Elision covers common cases; add explicit lifetimes to relate inputs/outputs
  • References in structs require lifetime parameters; 'static means program-long
  • Use lifetime bounds to express outlives relationships on generics