Function Lifetime Annotations
When a function returns a reference (&T, &mut T, &str, or a struct holding a reference), that returned reference must borrow from one of the function's reference parameters (or 'static). Function lifetime annotations (fn name<'a>(...) -> &'a ...) declare which input parameter(s) the returned reference is tied to.
Connecting Input and Output Lifetimes
Returning Data From One Specific Parameter
If a function takes two references (text and delimiter), uses delimiter only internally, and returns a sub-slice of text, only text shares 'a with the return type:
fn before_delimiter<'a>(text: &'a str, delimiter: &str) -> &'a str {
match text.find(delimiter) {
Some(idx) => &text[..idx],
None => text,
}
}
fn main() {
let path = String::from("/usr/local/bin:/usr/bin");
let first: &str;
{
let sep = String::from(":");
first = before_delimiter(&path, &sep);
} // `sep` drops here, but `first` only borrows `path`!
println!("First entry: '{first}'");
}
First entry: '/usr/local/bin'
Returning Data That May Come From Either Parameter
When the returned reference could come from either a or b, both parameters must be annotated with 'a so the return value lives for the overlap of both inputs:
fn shorter<'a>(a: &'a str, b: &'a str) -> &'a str {
if a.len() <= b.len() { a } else { b }
}
fn main() {
println!("Shorter: '{}'", shorter("rust", "toolchain"));
}
Shorter: 'rust'
Compiler Enforcement of the Lifetime Contract
If a signature promises fn bad<'a>(x: &'a str, y: &str) -> &'a str (tying the output solely to x), but the body returns y, rustc rejects it at compile time:
// ❌ does not compile
fn mismatch<'a>(x: &'a str, y: &str) -> &'a str {
let _ = x;
y
}
fn main() {}
error: lifetime may not live long enough
--> src/main.rs:4:5
|
2 | fn mismatch<'a>(x: &'a str, y: &str) -> &'a str {
| -- - let's call the lifetime of this reference `'1`
| |
| lifetime `'a` defined here
3 | let _ = x;
4 | y
| ^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'1`
error: aborting due to 1 previous error