Lifetimes in Structs
In this page:
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
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);
}
Login to try C/C++/Java/PHP code in the editor
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
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());
}
Login to try C/C++/Java/PHP code in the editor
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
struct Wrapper<'a> {
value: &'a i32,
}
fn main() {
let number = 42;
let wrapped = Wrapper { value: &number };
println!("{}", wrapped.value);
}
Login to try C/C++/Java/PHP code in the editor
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
struct OwnedExcerpt {
text: String,
}
fn main() {
let excerpt = OwnedExcerpt { text: String::from("No lifetime needed here") };
println!("{}", excerpt.text);
}
Login to try C/C++/Java/PHP code in the editor
- Trying to store a reference in a struct field without declaring a lifetime parameter on the struct itself, which fails to compile.
- Assuming a struct holding a reference can outlive the data that reference points to -- the compiler enforces the opposite.
- Forgetting an
implblock for a struct with a lifetime parameter must also repeat that lifetime, e.g.impl<'a> MyStruct<'a>.
- 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.
implblocks for a struct with a lifetime parameter must declare and repeat that same lifetime.- Storing owned data (like
Stringinstead 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: