100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace

Rust Lifetimes Cheat Sheet

Rust Lifetimes Cheat Sheet

Explains lifetime annotations, lifetime elision rules, structs holding references, and how the borrow checker uses lifetimes to prevent dangling references.

2 PagesAdvancedApr 10, 2026

Basic Lifetime Annotation

Annotating function signatures so the borrow checker can verify references.

rust
// 'a says: the returned reference lives at least as long as both x and yfn longest<'a>(x: &'a str, y: &'a str) -> &'a str {    if x.len() > y.len() { x } else { y }}fn main() {    let s1 = String::from("long string");    let result;    {        let s2 = String::from("short");        result = longest(s1.as_str(), s2.as_str());        println!("Longest: {}", result); // must be used before s2 drops    }}

Lifetime Elision Rules

When the compiler can infer lifetimes without explicit annotations.

  • Rule 1- Each elided input reference gets its own distinct lifetime parameter
  • Rule 2- If there's exactly one input lifetime, it's assigned to all elided output lifetimes
  • Rule 3- If a parameter is &self or &mut self, its lifetime is assigned to all elided output lifetimes
  • fn first_word(s: &str) -> &str- No annotations needed; elision infers the output borrows from s
  • When elision fails- The compiler requires explicit 'a annotations when multiple refs could be the source

Structs Holding References

A struct cannot outlive the data it borrows.

rust
// ImportantExcerpt cannot outlive the string slice it referencesstruct ImportantExcerpt<'a> {    part: &'a str,}impl<'a> ImportantExcerpt<'a> {    fn announce_and_return(&self, announcement: &str) -> &str {        println!("Attention: {}", announcement);        self.part    }}let novel = String::from("Call me Ishmael. Some years ago...");let first_sentence = novel.split('.').next().unwrap();let excerpt = ImportantExcerpt { part: first_sentence };

Lifetimes with Generics

Combining lifetime parameters, generic types, and trait bounds.

rust
use std::fmt::Display;// Combine a lifetime, a generic type, and a trait boundfn longest_with_announcement<'a, T>(x: &'a str, y: &'a str, ann: T) -> &'a strwhere    T: Display,{    println!("Announcement! {}", ann);    if x.len() > y.len() { x } else { y }}// T: 'a means: any references inside T must outlive 'astruct Wrapper<'a, T: 'a> {    value: &'a T,}

The 'static Lifetime

The special lifetime meaning "valid for the whole program".

  • 'static (reference)- The reference is valid for the entire duration of the program
  • String literals- &str literals like "hello" are 'static; stored directly in the binary
  • 'static bound on generics- Means T contains no non-'static references (owned data qualifies)
  • Common misuse- Don't reach for 'static to "fix" a lifetime error; it often just hides a real ownership issue
Pro Tip

Lifetime parameters don't change how long a value lives — they only describe constraints to the borrow checker so it can verify references don't outlive their data. If you're fighting lifetimes, consider whether owning the data (cloning, or using Rc) is simpler than threading references through.

Was this cheat sheet helpful?

Explore Topics

#RustLifetimes#RustLifetimesCheatSheet#Programming#Advanced#BasicLifetimeAnnotation#LifetimeElisionRules#StructsHoldingReferences#LifetimesWithGenerics#CheatSheet#SkillVeris