Slices and reference lifetimes
Slices and reference lifetimes
A report can use the first two marks without allocating a second collection. A slice is a borrowed view of consecutive elements. A lifetime describes how long a reference can validly be used; it does not keep the original data alive or allocate a copy.
What you’ll learn
- Borrow a valid prefix without copying elements.
- Explain what lifetime relationships require of the owners.
Slices and reference lifetimes in action
Owner: [70, 80, 90]
The first call selects the smaller of the collection length and two, then borrows that prefix.
Owner: [70, 80, 90]Borrow prefix: [70, 80]
No mark buffer is copied.
Borrow prefix: [70, 80]View cannot outlive owner
The empty slice has length zero, so its prefix is empty rather than out of bounds.
View cannot outlive owner
Slices and reference lifetimes explained
&marks[..2] borrows elements zero and one. A function returning a slice can tie its returned reference to the input reference. Rust’s lifetime elision rules infer that relationship here. Explicit lifetime annotations become useful when a signature has multiple relevant references; they describe relationships rather than changing how long values live.
Work through the Rust program
Save the complete source as main.rs in the Rust environment. No standard input is needed.
Rust 2024 · complete program
fn first_two(marks: &[i32]) -> &[i32] {
&marks[..marks.len().min(2)]
}
fn main() {
let marks = [70, 80, 90];
let preview = first_two(&marks);
println!("{preview:?}");
println!("{:?}", first_two(&[]));
}Expected output
[70, 80]
[]Follow the execution
The first call selects the smaller of the collection length and two, then borrows that prefix. No mark buffer is copied. The empty slice has length zero, so its prefix is empty rather than out of bounds. Preview remains valid while the original marks are available.
Try the complete program in the Rust compiler. For tests, Cargo commands and local files, use the specified local environment.
When a signature needs an explicit lifetime
When a function may return either of two input references, an explicit lifetime parameter can describe their relationship. Here the result must remain within the validity of the input borrows. The annotation does not allocate text or keep an owner alive.
Rust 2024 · complete program
fn longer<'a>(a: &'a str, b: &'a str) -> &'a str {
if a.len() >= b.len() { a } else { b }
}
fn main() {
let first = String::from("Diya");
let second = String::from("Saira");
println!("{}", longer(&first, &second));
}Expected output
SairaBoth Strings remain alive through printing. The helper compares byte lengths, selecting the five-byte name. If the selected borrow were used after its owner was dropped, the compiler would reject that use. This signature constrains the returned borrow even if a particular call could select the longer-lived input.
Try a small variation
Your task: Can first_two return a slice into a temporary array created inside the function?
Rust 2024 · complete program
fn first_two(marks: &[i32]) -> &[i32] {
&marks[..marks.len().min(2)]
}
fn main() {
let marks = [70, 80, 90];
let preview = first_two(&marks);
println!("{preview:?}");
println!("{:?}", first_two(&[]));
}Worked answer
No. That local array would be dropped when the function returns, leaving an invalid reference. Return owned data or borrow from an input that remains alive.
Mistakes and limits to recognize
Using a fixed ..2 slice on shorter input would panic, so the minimum calculation matters. String slices also require valid UTF-8 byte boundaries. Lifetime reasoning is about validity, not an estimate of how many milliseconds the operation takes.
Check your understanding
Apply the rule
Take the idea into your next program
No. That local array would be dropped when the function returns, leaving an invalid reference. Return owned data or borrow from an input that remains alive. Using a fixed ..2 slice on shorter input would panic, so the minimum calculation matters.
Further reading: the official Rust Book on slices and reference lifetimes.
Reaching the recap and completing the quizzes are separate milestones.