← Back to Rust Course | Chapter 12: Lifetimes | Lesson 4 of 6

Lifetimes in Structs

A struct that holds a borrowed value needs its own age label too, so Rust can guarantee it never outlives what it's borrowing from.

A Struct Holding a Reference

When a struct field is a reference, the struct itself needs a lifetime parameter, ensuring no instance of the struct can outlive the data it borrows.

Example: A Struct Holding a Reference

markup
struct Excerpt<'a> {
    text: &'a str,
}

fn main() {
    let novel = String::from("Call me Ishmael. Some years ago...");
    let first_sentence = novel.split('.').next().unwrap();
    let excerpt = Excerpt { text: first_sentence };
    println!("{}", excerpt.text);
}

Methods on a Struct with a Lifetime

An impl block for a struct that has a lifetime parameter must declare and repeat that lifetime, letting methods work with the borrowed field just like any other.

Example: Methods on a Struct with a Lifetime

markup
struct Excerpt<'a> {
    text: &'a str,
}

impl<'a> Excerpt<'a> {
    fn announce(&self) -> String {
        format!("Excerpt: {}", self.text)
    }
}

fn main() {
    let source = String::from("Rust is reliable and fast");
    let excerpt = Excerpt { text: &source[0..4] };
    println!("{}", excerpt.announce());
}

Instances Cannot Outlive Their Data

The compiler guarantees that a struct instance holding a reference cannot be used after the data it references has gone out of scope, preventing dangling struct fields entirely.

Example: Instances Cannot Outlive Their Data

markup
struct Wrapper<'a> {
    value: &'a i32,
}

fn main() {
    let number = 42;
    let wrapped = Wrapper { value: &number };
    println!("{}", wrapped.value);
}

Avoiding Lifetimes with Owned Data

If a struct owns its data (using String instead of &str, for example) it needs no lifetime parameter at all, trading a small allocation cost for simpler code.

Example: Avoiding Lifetimes with Owned Data

markup
struct OwnedExcerpt {
    text: String,
}

fn main() {
    let excerpt = OwnedExcerpt { text: String::from("No lifetime needed here") };
    println!("{}", excerpt.text);
}
Common Mistakes
  1. Trying to store a reference in a struct field without declaring a lifetime parameter on the struct itself, which fails to compile.
  2. Assuming a struct holding a reference can outlive the data that reference points to -- the compiler enforces the opposite.
  3. Forgetting an impl block for a struct with a lifetime parameter must also repeat that lifetime, e.g. impl<'a> MyStruct<'a>.
Chapter Summary
  • A struct holding a reference field must declare a lifetime parameter, e.g. struct Excerpt<'a> { text: &'a str }.
  • An instance of such a struct cannot outlive the data its reference field points to.
  • impl blocks for a struct with a lifetime parameter must declare and repeat that same lifetime.
  • Storing owned data (like String instead of &str) avoids needing a lifetime parameter, at the cost of an extra allocation.
🔒

Chapter Quiz — Complete all 6 topics to unlock

0/6 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.