Lifetimes ('a)
A lifetime is an annotation that indicates the scope for which a reference is valid. The compiler uses lifetimes to detect dangling references. You write them explicitly when you need to relate the lifetimes of multiple references in functions or structs.
Syntax
// Lifetime annotation in a function signature
fn function_name<'a>(x: &'a str, y: &'a str) -> &'a str { ... }
// Lifetime in a struct field
struct StructName<'a> {
field: &'a str,
}
// Static lifetime (valid for the entire program)
let s: &'static str = "hello";
Lifetime Notation
| Notation | Description |
|---|---|
| 'a | A lifetime parameter. Any name can be used, but by convention it starts with 'a. |
| &'a T | An immutable reference to type T with lifetime 'a. |
| &'a mut T | A mutable reference to type T with lifetime 'a. |
| 'static | A special lifetime that is valid for the entire duration of the program. String literals have this lifetime. |
Sample Code
// Returns the longer of two string slices.
// The return value has the same lifetime as the arguments.
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() {
x
} else {
y
}
}
// A struct that holds a reference with a lifetime
struct Important<'a> {
content: &'a str,
}
impl<'a> Important<'a> {
fn display(&self) {
println!("{}", self.content);
}
}
fn main() {
let s1 = String::from("long string");
let result;
{
let s2 = String::from("xyz");
result = longest(s1.as_str(), s2.as_str());
println!("Longest: {}", result); // result can only be used while s2 is valid.
}
// Static lifetime
let s: &'static str = "Valid until the program ends";
println!("{}", s);
let novel = String::from("The story begins. In the next chapter...");
let first_sentence;
{
let i = Important {
content: novel.split('.').next().unwrap(),
};
i.display();
first_sentence = i.content;
}
println!("{}", first_sentence);
}
Notes
Lifetime annotations do not change how long a reference is valid — they simply tell the compiler about the relationship between the lifetimes of multiple references. In many cases, the compiler can infer lifetimes automatically through "lifetime elision rules," so explicit annotations are not always required.
A lifetime mismatch causes a compile error. When a function returns a reference, the lifetime of the return value must be tied to the lifetime of one of its parameters.
For the basics of references, see Borrowing / References (&).
If you find any errors or copyright issues, please contact us.