RustCurious.com
Rust explained carefully.

Lifetimes Cheat Sheet

Explained in these videos:

All the examples below apply equally to shared references and mutable references.

Elided lifetimes

When a function returns a reference, the lifetime can be “elided” (left out) if:

One input reference

// Returns Data owned by *x
fn get_data(x: &🟦Foo) -> &🟦Data

Multiple input references

// Returns Data owned by *x
fn from_x<'a>(x: &'a Foo, y: &Foo) -> &'a Data

// Returns Data owned by *y
fn from_y<'a>(x: &Foo, y: &'a Foo) -> &'a Data

// Returns Data that could be owned by *x or *y
fn either<'a>(x: &'a Foo, y: &'a Foo) -> &'a Data

Self by reference

impl Foo {
    // Returns Data owned by *self
    fn get_mine(&🟦self, other: &Foo) -> &🟦Data

    // Returns Data owned by *other
    fn get_theirs<'a>(&self, other: &'a Foo) -> &'a Data

    // Returns Data that could be owned by *self or *other
    fn get_either<'a>(&'a self, other: &'a Foo) -> &'a Data
}

Types holding references

struct Iter<'a> {
    key: Key,       // `Key` owned by Iter
    map: &'a Map,  // `Map` owned elsewhere
}

impl<'a> Iter<'a> {
    // Returns Key owned by *self
    fn key(&🟦self) -> &🟦Key {
        &self.key
    }

    // Returns Map that outlives *self
    fn map(&self) -> &'a Map {
        self.map
    }
}

Lifetime bounds

T: 'a means T must be valid for at least 'a

Reference to a generic type:&'a T  requires  T: 'a  (in case T is a reference)
Reference to a reference:&'a &'b Data  requires  'b: 'a