Course contentsShow
← Rust
Lesson 349 of 1,9104. Lifetimes and Advanced OwnershipFree lesson

Ownership in Struct Definitions

Define structs that own their data versus those that hold references.

In this lesson, you will learn how to design structs that either take full ownership of their data or merely reference it, and why this distinction is critical for memory safety.

Structs that Own Their Data

Most of the time, when you define a struct in Rust, you want it to be self-contained. When a struct holds owned types like String, Vec, or Box, it is responsible for the entire lifecycle of that data. If the struct goes out of scope, the data it owns is cleaned up immediately.

struct User {
    username: String, // The struct owns this String
    email: String,
}

In this case, the User struct "lives" with its data. When a User instance is dropped, the String buffers are deallocated from the heap. This is the simplest and most common way to build data structures in Rust.

Structs that Hold References

Sometimes, you may want a struct to point to data owned by someone else. This is useful for performance—such as avoiding expensive deep copies of large strings or arrays. However, because Rust must ensure memory safety, it cannot allow a struct to outlive the data it points to. If you put a reference inside a struct, the compiler forces you to annotate it with a lifetime:

struct UserRef<'a> {
    username: &'a str, // The struct holds a reference
}

The 'a syntax is a lifetime parameter. It tells the compiler: "This UserRef cannot exist longer than the string it is referencing." If you try to destroy the original string while the UserRef is still in use, the borrow checker will stop you.

Choosing the Right Approach

  • Choose Ownership when your struct is a standalone entity that should manage its own memory. It is easier to reason about, as you don't need to track external dependencies.
  • Choose References when you are building a tool that needs to view data in place (like a parser or a search algorithm) and you need to avoid the overhead of cloning large amounts of data.

Key Takeaway: A struct either manages its data’s lifetime by owning it, or it must use lifetime annotations to guarantee it never outlives the data it references.