Bird
Raised Fist0
Rustprogramming~5 mins

Lifetime annotations in Rust - Cheat Sheet & Quick Revision

Choose your learning style10 modes available
Recall & Review
beginner
What is a lifetime annotation in Rust?
A lifetime annotation tells Rust how long a reference should be valid. It helps the compiler check that references do not outlive the data they point to.
Click to reveal answer
beginner
Why do we need lifetime annotations in Rust?
We need lifetime annotations to avoid dangling references and ensure memory safety by making sure references do not live longer than the data they refer to.
Click to reveal answer
intermediate
Explain the syntax of a lifetime annotation with an example.
A lifetime annotation uses an apostrophe followed by a name, like 'a. For example, fn example<'a>(x: &'a str) -> &'a str means the returned reference lives at least as long as x.
Click to reveal answer
intermediate
What does the following function signature mean?
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str
It means both input string references x and y must live at least as long as lifetime 'a, and the returned reference will also live at least as long as 'a. This ensures the returned reference is valid as long as both inputs.
Click to reveal answer
intermediate
Can Rust always infer lifetimes without annotations?
Rust can infer lifetimes in simple cases using lifetime elision rules. But for complex cases, explicit lifetime annotations are needed to clarify how references relate.
Click to reveal answer
What does a lifetime annotation in Rust specify?
AHow long a reference is valid
BThe size of a variable
CThe type of a variable
DThe value of a variable
Which symbol starts a lifetime annotation in Rust?
A$
B&
C#
D'
In the function signature fn foo<'a>(x: &'a i32) -> &'a i32, what does 'a represent?
AA type parameter
BA lifetime parameter
CA variable name
DA constant value
Why might Rust require explicit lifetime annotations?
ATo clarify complex reference relationships
BTo improve performance
CTo reduce code size
DTo allow unsafe code
What happens if a reference outlives the data it points to in Rust?
AThe reference becomes null
BThe program crashes immediately
CRust compiler gives an error
DRust ignores it
Explain in your own words what lifetime annotations are and why they are important in Rust.
Think about how Rust keeps track of how long references are valid.
You got /3 concepts.
    Describe the syntax of lifetime annotations and give a simple example function signature using them.
    Look at how <code>&#39;a</code> is used in function parameters and return types.
    You got /3 concepts.

      Practice

      (1/5)
      1. What is the main purpose of lifetime annotations in Rust?
      easy
      A. To tell Rust how long references are valid
      B. To specify variable types explicitly
      C. To manage memory allocation manually
      D. To define function return types only

      Solution

      1. Step 1: Understand lifetime annotations role

        Lifetime annotations tell Rust the scope of references to avoid dangling pointers.
      2. Step 2: Compare with other options

        Other options describe unrelated concepts like type specification or memory management.
      3. Final Answer:

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

        Lifetime annotations = reference validity [OK]
      Hint: Lifetime annotations connect reference scopes [OK]
      Common Mistakes:
      • Confusing lifetimes with types
      • Thinking lifetimes manage memory directly
      • Assuming lifetimes only affect return types
      2. Which of the following is the correct syntax to declare a lifetime parameter named 'a in a function signature?
      easy
      A. fn example(input: &'a str) -> str<'a>
      B. fn example<'a>(input: &'a str) -> &'a str
      C. fn example<'a>(input: &str<'a>) -> &str
      D. fn example(a: &str) -> &str<'a>

      Solution

      1. Step 1: Identify correct lifetime syntax

        Lifetime parameters are declared with apostrophe before the name in angle brackets: 'a and used in references.
      2. Step 2: Check each option

        fn example<'a>(input: &'a str) -> &'a str correctly declares 'a and uses it for input and output references. Others misuse syntax or place lifetime incorrectly.
      3. Final Answer:

        fn example<'a>(input: &'a str) -> &'a str -> Option B
      4. Quick Check:

        Lifetime syntax = fn example<'a>(input: &'a str) [OK]
      Hint: Declare lifetimes in angle brackets before parameters [OK]
      Common Mistakes:
      • Placing lifetime after type instead of before
      • Omitting lifetime declaration in angle brackets
      • Using lifetime on non-reference types
      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 string1 = String::from("apple");
          let string2 = "banana";
          let result = longest(string1.as_str(), string2);
          println!("{}", result);
      }
      medium
      A. Runtime error
      B. apple
      C. Compilation error due to lifetimes
      D. banana

      Solution

      1. Step 1: Understand function longest behavior

        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 and returned.
      3. Final Answer:

        banana -> Option D
      4. Quick Check:

        Longest string = banana [OK]
      Hint: Compare lengths to find longest string [OK]
      Common Mistakes:
      • Assuming compilation error due to lifetimes
      • Confusing which string is longer
      • Expecting runtime error from references
      4. Identify the error in this Rust code snippet involving lifetimes:
      fn first_word<'a>(s: &str) -> &'a 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 parameter s
      B. Cannot return a slice of s without cloning
      C. Return type lifetime 'a does not match input lifetime
      D. Function should return String, not &str

      Solution

      1. Step 1: Check lifetime annotations on parameters and return

        The parameter s has no lifetime annotation, so Rust assigns an implicit lifetime. The return type has explicit lifetime 'a which is unrelated.
      2. Step 2: Understand lifetime mismatch

        The return lifetime 'a must be tied to the input lifetime to ensure safety. Here, 'a is unrelated, causing a mismatch error.
      3. Final Answer:

        Return type lifetime 'a does not match input lifetime -> Option C
      4. Quick Check:

        Return lifetime must match input lifetime [OK]
      Hint: Return lifetime must match input reference lifetime [OK]
      Common Mistakes:
      • Forgetting to add lifetime to input parameter
      • Assuming cloning is needed for slices
      • Confusing &str and String return types
      5. Given two string slices with different lifetimes, how can you write a function that returns the longer slice safely using lifetime annotations? Choose the correct function signature.
      hard
      A. fn longest<'a>(x: &'a str, y: &'a str) -> &'a str
      B. fn longest<'a, 'b>(x: &'a str, y: &'b str) -> &'a str
      C. fn longest<'a, 'b>(x: &'a str, y: &'b str) -> &'b str
      D. fn longest(x: &str, y: &str) -> &str

      Solution

      1. Step 1: Understand lifetime requirements for return

        The returned reference must be valid as long as both inputs. Using a single lifetime 'a for both inputs and output ensures this.
      2. Step 2: Analyze options

        fn longest<'a>(x: &'a str, y: &'a str) -> &'a str uses one lifetime parameter for both inputs and output, guaranteeing safety. fn longest<'a, 'b>(x: &'a str, y: &'b str) -> &'a str and C use different lifetimes, which can cause unsafe returns. fn longest(x: &str, y: &str) -> &str omits lifetimes, causing errors.
      3. Final Answer:

        fn longest<'a>(x: &'a str, y: &'a str) -> &'a str -> Option A
      4. Quick Check:

        Single lifetime for inputs and output [OK]
      Hint: Use one lifetime for all references to ensure safety [OK]
      Common Mistakes:
      • Using different lifetimes for inputs and output
      • Omitting lifetime annotations causing errors
      • Assuming &str without lifetimes is enough
      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