In this lesson, you will learn how to use lifetime annotations to explicitly describe the relationship between the lifespan of input references and the lifespan of the references you return from a function.
The Problem of Ambiguity
When a function takes a reference as an input and returns a reference, the Rust compiler needs to know if the returned reference is pointing to the memory of the first input, the second input, or something else entirely. If the compiler cannot guarantee that the returned reference will remain valid, it will refuse to compile your code to prevent a dangling reference.
Most of the time, the compiler can "guess" these relationships using simple rules, but sometimes it needs a little help. We use lifetime annotations (marked with an apostrophe, like 'a) to create a label that tells the compiler: "This output reference will live exactly as long as this specific input reference."
Labeling Lifetimes
Consider a function that returns the longer of two strings:
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() {
x
} else {
y
}
}
Here, we declare a lifetime parameter 'a inside angle brackets. By placing 'a next to x, y, and the return type, we are telling the borrow checker: "The reference returned by this function is guaranteed to be valid for at least as long as the inputs x and y."
Why this matters
These annotations don't actually change how long your data lives in memory. Instead, they act as a contract. By annotating the signature, you are providing the compiler with enough information to verify that you aren't returning a reference to a variable that might have gone out of scope or been cleaned up by a destructor. If you try to return a value that doesn't fit the contract established by your lifetime labels, the compiler will catch it, keeping your program memory-safe.
Key Takeaway: Lifetime annotations are labels that describe the relationship between the scopes of input references and return references, allowing the compiler to prove that your program won't access invalid memory.