Bird
Raised Fist0
Rustprogramming~20 mins

Lifetimes in functions in Rust - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Rust Lifetimes Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
What is the output of this Rust code with lifetimes?
Consider the following Rust function that returns a reference with a lifetime parameter. What will be printed when running this code?
Rust
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!("Longest string is: {}", result);
}
ARuntime error due to dangling reference
BLongest string is: apple
CCompilation error due to lifetime mismatch
DLongest string is: banana
Attempts:
2 left
💡 Hint
Think about which string is longer and how lifetimes ensure safety.
❓ Predict Output
intermediate
2:00remaining
What happens with this Rust code?
This Rust function returns a reference without explicit lifetimes. What happens when compiling and running?
Rust
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[..]
}

fn main() {
    let my_string = String::from("hello world");
    let word = first_word(&my_string);
    println!("First word: {}", word);
}
ANo error, prints: First word: hello
BError: cannot return reference to local variable
CError: missing lifetime specifier in function signature
DError: mismatched types between &str and String
Attempts:
2 left
💡 Hint
Rust has lifetime elision rules that infer lifetimes in common cases.
🔧 Debug
advanced
2:00remaining
Why does this Rust code fail to compile due to lifetimes?
This Rust code tries to return a reference from a function, but it fails to compile. Identify the cause of the error.
Rust
fn get_str() -> &str {
    let s = String::from("hello");
    &s
}

fn main() {
    let result = get_str();
    println!("{}", result);
}
ANo error, prints: hello
BError: returning reference to local variable 's' which will be dropped
CError: cannot move out of borrowed content
DError: missing lifetime specifier in function signature
Attempts:
2 left
💡 Hint
Think about the scope and lifetime of the variable 's'.
📝 Syntax
advanced
2:00remaining
Which function signature correctly uses lifetimes for two input references and returns one?
You want a function that takes two string slices and returns one of them with the correct lifetime annotations. Which signature is correct?
Afn choose(x: &str, y: &str) -> &str
Bfn choose<'a, 'b>(x: &'a str, y: &'b str) -> &'a str
Cfn choose<'a>(x: &'a str, y: &'a str) -> &'a str
Dfn choose<'a>(x: &'a str, y: &'a str) -> &str
Attempts:
2 left
💡 Hint
The returned reference lifetime must be tied to both inputs.
❓ Predict Output
expert
3:00remaining
What is the output of this Rust code using lifetime bounds in structs and functions?
Analyze the following Rust code with a struct holding a reference with a lifetime. What will be printed?
Rust
struct ImportantExcerpt<'a> {
    part: &'a str,
}

impl<'a> ImportantExcerpt<'a> {
    fn announce_and_return_part(&self, announcement: &str) -> &str {
        println!("Attention please: {}", announcement);
        self.part
    }
}

fn main() {
    let novel = String::from("Call me Ishmael. Some years ago...");
    let first_sentence = novel.split('.').next().expect("Could not find a '.'");
    let excerpt = ImportantExcerpt { part: first_sentence };
    let result = excerpt.announce_and_return_part("Here is the excerpt");
    println!("Excerpt: {}", result);
}
A
Attention please: Here is the excerpt
Excerpt: Call me Ishmael
B
Attention please: Here is the excerpt
Excerpt: Call me Ishmael. Some years ago
CRuntime panic due to unwrap on None
DCompilation error due to missing lifetime annotations in impl
Attempts:
2 left
💡 Hint
Look at how the string is split and what part is stored in the struct.

Practice

(1/5)
1. What is the main purpose of lifetimes in Rust functions?
easy
A. To control thread execution order
B. To tell Rust how long references are valid
C. To define variable types explicitly
D. To manage memory allocation size

Solution

  1. Step 1: Understand lifetimes concept

    Lifetimes specify how long references remain valid to prevent dangling pointers.
  2. Step 2: Identify purpose in functions

    Functions use lifetimes to connect input and output references safely.
  3. Final Answer:

    To tell Rust how long references are valid -> Option B
  4. Quick Check:

    Lifetimes = reference validity [OK]
Hint: Lifetimes track reference validity duration [OK]
Common Mistakes:
  • Confusing lifetimes with memory size
  • Thinking lifetimes manage variable types
  • Assuming lifetimes control threads
2. Which of the following is the correct syntax to declare a function with a lifetime parameter 'a that returns a reference with the same lifetime?
easy
A. fn example<'a>(x: &'a str) -> &'a str { x }
B. fn example(x: &str) -> &str { x }
C. fn example<'a>(x: &str) -> &'a str { x }
D. fn example(x: &'a str) -> &str { x }

Solution

  1. Step 1: Identify lifetime parameter usage

    The lifetime 'a must be declared and used consistently in parameters and return type.
  2. Step 2: Check each option's correctness

    fn example<'a>(x: &'a str) -> &'a str { x } correctly declares 'a and uses it for input and output references.
  3. Final Answer:

    fn example<'a>(x: &'a str) -> &'a str { x } -> Option A
  4. Quick Check:

    Lifetime declared and used consistently [OK]
Hint: Declare and use lifetime parameter consistently [OK]
Common Mistakes:
  • Omitting lifetime declaration
  • Using lifetime only in return type
  • Using lifetime only in parameter
3. What will be the output of this Rust code?
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);
}
medium
A. Runtime error
B. apple
C. Compilation error due to lifetimes
D. banana

Solution

  1. Step 1: Understand function logic

    The function returns the longer string slice between x and y.
  2. Step 2: Compare string lengths

    "apple" has 5 letters, "banana" has 6 letters, so "banana" is longer.
  3. Final Answer:

    banana -> Option D
  4. Quick Check:

    Longest string = banana [OK]
Hint: Compare lengths, return longer string slice [OK]
Common Mistakes:
  • Assuming compilation error due to lifetimes
  • Confusing which string is longer
  • Expecting runtime error
4. Identify the error in this Rust function and how to fix it:
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
}
medium
A. Missing lifetime annotation on function signature
B. Incorrect byte comparison syntax
C. Return type should be String, not &str
D. Function should take String, not &str

Solution

  1. Step 1: Analyze function signature

    The function returns a reference to a slice of the input string, so lifetimes must be connected.
  2. Step 2: Identify missing lifetime annotation

    Without lifetime 'a, Rust cannot ensure the returned reference is valid as long as input.
  3. Final Answer:

    Missing lifetime annotation on function signature -> Option A
  4. Quick Check:

    Lifetime needed for input and output references [OK]
Hint: Add lifetime to input and output references [OK]
Common Mistakes:
  • Ignoring lifetime errors
  • Changing return type unnecessarily
  • Confusing byte comparison syntax
5. Given two string slices with different lifetimes, how can you write a function that returns the longer slice without lifetime errors?
fn longest(x: &str, y: &str) -> &str {
    if x.len() > y.len() { x } else { y }
}
hard
A. Use different lifetime parameters for inputs and output
B. Return a String instead of a reference to avoid lifetimes
C. Add a single lifetime parameter 'a to both inputs and output: fn longest<'a>(x: &'a str, y: &'a str) -> &'a str
D. Remove references and pass owned Strings

Solution

  1. Step 1: Understand lifetime mismatch

    Without lifetime annotations, Rust cannot guarantee output reference lives as long as inputs.
  2. Step 2: Use a single lifetime parameter

    Declaring 'a for both inputs and output ties their lifetimes together, resolving errors.
  3. Final Answer:

    Add a single lifetime parameter 'a to both inputs and output: fn longest<'a>(x: &'a str, y: &'a str) -> &'a str -> Option C
  4. Quick Check:

    Single lifetime parameter ties input/output lifetimes [OK]
Hint: Use one lifetime parameter for all references [OK]
Common Mistakes:
  • Using different lifetimes for inputs and output
  • Returning owned String unnecessarily
  • Removing references instead of fixing lifetimes
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard