Lifetimes ensure references are valid for as long as they're used. Most are inferred, but sometimes you need explicit annotations.
// This won't compile - which input does the return reference come from?
fn longest(x: &str, y: &str) -> &str {
if x.len() > y.len() { x } else { y }
}The compiler doesn't know if the returned reference comes from x or y, so it can't verify the reference will be valid.
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() { x } else { y }
}Lifetime annotations don't change how long references live. They describe relationships between lifetimes so the compiler can check validity.
'a - a lifetime parameter (convention: lowercase letters)&'a T - a reference with lifetime 'a&'a mut T - a mutable reference with lifetime 'a'static - the entire program durationThe compiler applies these rules automatically:
&self or &mut self, that lifetime applies to outputsstruct ImportantExcerpt<'a> {
part: &'a str, // This reference must live at least as long as the struct
}Add lifetime annotations to make longest compile.
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() {
x
} else {
y
}
}The 'a says: "The returned reference will be valid for the shorter of the two input lifetimes."