C.W.K.
Stream
Lesson 04 of 05 · published

Lifetimes in Structs

~11 min · lifetimes, structs, borrowed-fields

Level 0Rust Curious
0 XP0/80 lessons0/19 achievements
0/100 XP to next level100 XP to go0% complete

Structs usually own their data. But sometimes you want a struct to hold a reference — and the moment it does, the struct needs a lifetime annotation.

A struct that borrows

If a struct field is a reference, the struct can't outlive whatever that reference points at. Otherwise the struct would hold a dangling reference — exactly what the borrow checker forbids. So you annotate the struct with a lifetime, tying the struct's validity to the borrowed data's.

What the annotation enforces

A struct declared with 'a can't outlive the data its reference borrows. Try to keep the struct around after the borrowed value drops, and the compiler refuses. The annotation isn't bookkeeping for its own sake — it's the compiler propagating the 'references can't dangle' rule through your own types.

Prefer owned fields unless you have a reason to borrow. A struct holding a String owns its data and has no lifetime headaches. A struct holding a &str avoids a copy but ties itself to the borrowed source. Reach for borrowed fields only when the copy genuinely matters.

This is where beginners feel the wall

Reference-holding structs are where lifetime annotations cascade — a borrowed field forces a lifetime on the struct, on its impl blocks, and on methods returning the field. It's the most annotation-heavy corner of everyday Rust, and the honest advice is: start with owned fields, reach for borrows only when profiling says the copy matters.

Code

A struct that holds a reference·rust
// The struct can't outlive the str it borrows.
struct Excerpt<'a> {
    part: &'a str,
}

impl<'a> Excerpt<'a> {
    fn announce(&self) -> &str {
        self.part
    }
}

fn main() {
    let novel = String::from("Call me Ishmael. Some years ago...");
    let first = novel.split('.').next().unwrap();
    let e = Excerpt { part: first }; // borrows from novel
    println!("{}", e.announce());
    // `e` cannot outlive `novel` — the compiler guarantees it
}

External links

Exercise

Define a struct with a &str field and a lifetime. Create an instance that borrows from a String, then try to drop the String while still using the struct. Read the error. Then rewrite the struct to own a String field instead — notice the lifetime annotation disappears entirely.
Hint
Owning the data removes the borrow relationship, so there's nothing to annotate. That's why owned fields are the simpler default — they sidestep lifetimes completely.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue
💛 by Ttoriwarm

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.