Lifetimes help Rust know how long references are valid. This keeps your program safe from using data that no longer exists.
Lifetimes in functions in Rust
fn function_name<'a>(param: &'a Type) -> &'a Type { // function body }
The &'a means a reference with lifetime 'a.
You declare lifetime parameters with <'a> after the function name.
'a ties the output to the input, so Rust knows the returned reference is valid as long as the input is.fn first_word<'a>(s: &'a str) -> &'a str { let bytes = s.as_bytes(); for (i, &item) in bytes.iter().enumerate() { if item == b' ' { return &s[0..i]; } } &s[..] }
'a, so Rust knows the output reference is valid as long as both inputs are.fn longest<'a>(x: &'a str, y: &'a str) -> &'a str { if x.len() > y.len() { x } else { y } }
This program defines a function longest that returns the longer of two string slices. The lifetime 'a ensures the returned reference is valid as long as both inputs are valid. In main, it prints the longer string.
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str { if x.len() > y.len() { x } else { y } } fn main() { let string1 = String::from("apple"); let string2 = "banana"; let result = longest(string1.as_str(), string2); println!("The longest string is: {}", result); }
Every reference in Rust has a lifetime, even if you don't write it explicitly.
Using lifetimes helps prevent bugs where you use data after it's gone.
If you don't specify lifetimes when needed, Rust will give an error to keep your code safe.
Lifetimes tell Rust how long references are valid.
Functions with references often need lifetime annotations to connect input and output lifetimes.
This helps Rust prevent bugs with invalid references and keeps your program safe.
Practice
Solution
Step 1: Understand lifetimes concept
Lifetimes specify how long references remain valid to prevent dangling pointers.Step 2: Identify purpose in functions
Functions use lifetimes to connect input and output references safely.Final Answer:
To tell Rust how long references are valid -> Option BQuick Check:
Lifetimes = reference validity [OK]
- Confusing lifetimes with memory size
- Thinking lifetimes manage variable types
- Assuming lifetimes control threads
'a that returns a reference with the same lifetime?Solution
Step 1: Identify lifetime parameter usage
The lifetime'amust be declared and used consistently in parameters and return type.Step 2: Check each option's correctness
fn example<'a>(x: &'a str) -> &'a str { x } correctly declares'aand uses it for input and output references.Final Answer:
fn example<'a>(x: &'a str) -> &'a str { x } -> Option AQuick Check:
Lifetime declared and used consistently [OK]
- Omitting lifetime declaration
- Using lifetime only in return type
- Using lifetime only in parameter
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() { x } else { y }
}
fn main() {
let s1 = String::from("apple");
let s2 = String::from("banana");
let result = longest(&s1, &s2);
println!("{}", result);
}Solution
Step 1: Understand function logic
The function returns the longer string slice betweenxandy.Step 2: Compare string lengths
"apple" has 5 letters, "banana" has 6 letters, so "banana" is longer.Final Answer:
banana -> Option DQuick Check:
Longest string = banana [OK]
- Assuming compilation error due to lifetimes
- Confusing which string is longer
- Expecting runtime error
fn first_word(s: &str) -> &str {
let bytes = s.as_bytes();
for (i, &item) in bytes.iter().enumerate() {
if item == b' ' {
return &s[0..i];
}
}
&s
}Solution
Step 1: Analyze function signature
The function returns a reference to a slice of the input string, so lifetimes must be connected.Step 2: Identify missing lifetime annotation
Without lifetime'a, Rust cannot ensure the returned reference is valid as long as input.Final Answer:
Missing lifetime annotation on function signature -> Option AQuick Check:
Lifetime needed for input and output references [OK]
- Ignoring lifetime errors
- Changing return type unnecessarily
- Confusing byte comparison syntax
fn longest(x: &str, y: &str) -> &str {
if x.len() > y.len() { x } else { y }
}Solution
Step 1: Understand lifetime mismatch
Without lifetime annotations, Rust cannot guarantee output reference lives as long as inputs.Step 2: Use a single lifetime parameter
Declaring'afor both inputs and output ties their lifetimes together, resolving errors.Final Answer:
Add a single lifetime parameter'ato both inputs and output:fn longest<'a>(x: &'a str, y: &'a str) -> &'a str-> Option CQuick Check:
Single lifetime parameter ties input/output lifetimes [OK]
- Using different lifetimes for inputs and output
- Returning owned String unnecessarily
- Removing references instead of fixing lifetimes
Ready to prove it?
Pass the test and this pattern moves unknown
