← Back to Rust Course | Chapter 12: Lifetimes | Lesson 3 of 6

Lifetimes in Functions

When a function hands back a borrowed value, it has to explain which of its inputs that borrowed value actually came from.

Returning a Reference Tied to a Parameter

When a function might return either of two reference parameters, an explicit lifetime annotation tells the compiler the returned reference is valid for as long as both inputs are.

Example: Returning a Reference Tied to a Parameter

markup
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("short");
    let s2 = String::from("a bit longer");
    println!("{}", longest(&s1, &s2));
}

Lifetime Elision for Simple Functions

For functions with exactly one reference parameter and a reference return type, Rust's elision rules infer the lifetime automatically, so no explicit annotation is needed.

Example: Lifetime Elision for Simple Functions

markup
fn first_char(s: &str) -> &str {
    &s[0..1]
}

fn main() {
    let word = "Rust";
    println!("{}", first_char(word));
}

Why You Cannot Return a Reference to a Local Variable

A function can never validly return a reference to data it created locally, since that data is dropped when the function returns; the fix is to return an owned value instead.

Example: Why You Cannot Return a Reference to a Local Variable

markup
fn build_owned() -> String {
    let local = String::from("owned and returned safely");
    local
}

fn main() {
    println!("{}", build_owned());
}

Functions with Independent Lifetimes

When a function's return value only relates to one of several reference parameters, giving each parameter its own independent lifetime clarifies that relationship precisely.

Example: Functions with Independent Lifetimes

markup
fn describe<'a>(name: &'a str, _ignored: &str) -> &'a str {
    name
}

fn main() {
    let name = String::from("Rustacean");
    let other = String::from("unrelated");
    println!("{}", describe(&name, &other));
}
Common Mistakes
  1. Trying to return a reference from a function without any lifetime annotation when the compiler cannot infer which input it relates to.
  2. Assuming a function can return a reference to data created entirely inside itself -- that data does not outlive the function call.
  3. Forgetting that lifetime elision rules already cover many common single-reference-parameter functions automatically.
Chapter Summary
  • A function returning a reference must specify which parameter's lifetime the return value is tied to.
  • Lifetime elision rules let the compiler infer lifetimes automatically for many simple, common function shapes.
  • A function can never return a reference to purely local data -- it must return an owned value or a reference tied to a parameter.
  • When a function has multiple reference parameters and returns one of them conditionally, an explicit lifetime is usually required.
🔒

Chapter Quiz — Complete all 6 topics to unlock

0/6 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.