0Pricing
Learn Rust Coding · Lesson

Lifetimes in Structs

Borrowed fields.

Lifetimes in Structs is a free Learn Rust Coding lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Learn Rust Coding learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

Structs Can Borrow

Most structs own their data. But a struct can also hold a reference to data it does not own. When it does, the struct needs a lifetime parameter.

This guarantees the struct never outlives the borrowed data.

Declaring a Lifetime on a Struct

Add the lifetime in angle brackets after the struct name, then use it on the reference field. This says the struct cannot outlive that reference.

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

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

The Constraint It Adds

The annotation means an instance of Excerpt is valid only while the string it borrows is alive. The compiler enforces this everywhere the struct is used.

Methods on Borrowing Structs

Methods on such a struct also carry the lifetime in the impl header. Often you can omit lifetimes in the method body thanks to elision (covered next lesson).

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

impl<'a> Excerpt<'a> {
    fn announce(&self) -> &str {
        println!("Attention!");
        self.text
    }
}

fn main() {
    let s = String::from("hello world");
    let e = Excerpt { text: &s };
    println!("{}", e.announce());
}

Why Not Just Own the Data?

Owning (using String) is simpler and usually preferred. Borrowing avoids copying large data and is useful for parsers and views that look into existing buffers.

Reach for lifetimes in structs only when borrowing pays off.

A Parser View Example

A struct that holds slices into a source string is a classic use. It reads the original buffer without copying.

struct Token<'a> {
    word: &'a str,
}

fn main() {
    let line = String::from("let x = 5");
    let tokens: Vec<Token> = line.split_whitespace().map(|w| Token { word: w }).collect();
    for t in &tokens {
        println!("token: {}", t.word);
    }
}

Multiple Reference Fields

A struct may hold several references. They can share one lifetime or use distinct ones, depending on how their validity relates.

struct Pair<'a> {
    left: &'a str,
    right: &'a str,
}

fn main() {
    let a = String::from("foo");
    let b = String::from("bar");
    let p = Pair { left: &a, right: &b };
    println!("{} {}", p.left, p.right);
}

The Dangling Struct Error

If the borrowed data is dropped while the struct still exists, the compiler rejects it. The lifetime parameter is what makes this check possible.

Returning Borrowing Structs

A function building such a struct ties the struct's lifetime to its input. The struct cannot outlive the data passed in.

struct Wrap<'a> { inner: &'a str }

fn wrap<'a>(s: &'a str) -> Wrap<'a> {
    Wrap { inner: s }
}

fn main() {
    let text = String::from("wrapped");
    let w = wrap(&text);
    println!("{}", w.inner);
}

Owned vs Borrowed Trade-off

Quick guide:

  • Need to keep data around independently? Own it (String, Vec).
  • Short-lived view into existing data? Borrow it with a lifetime.

Mental Model

A struct with 'a is like a sticky note attached to someone else's notebook: it is only meaningful while that notebook still exists. Rust makes sure you never read a note on a notebook that is gone.

Quick Check

Test your understanding of lifetimes in structs.

Recap

You learned lifetimes in structs:

  • A struct holding a reference needs a lifetime parameter
  • The lifetime ties the struct's validity to the borrowed data
  • Methods carry the lifetime in the impl header
  • Prefer owning unless borrowing avoids meaningful copies

Frequently asked questions

Is the “Lifetimes in Structs” lesson free?

Yes — the full text of “Lifetimes in Structs” is free to read here on the web, and the Learn Rust Coding course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Learn Rust Coding course, upgrade to CoddyKit PRO.

What will I learn in “Lifetimes in Structs”?

Borrowed fields. You practise Learn Rust Coding with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Learn Rust Coding?

No prior experience is required. Learn Rust Coding on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Lifetimes in Structs” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Learn Rust Coding lesson?

Yes. Every Learn Rust Coding lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Why Lifetimes
  2. Lifetime Annotations
  3. Lifetimes in Structs
  4. Elision Rules
← Back to Learn Rust Coding