Bird
Raised Fist0
Rustprogramming~10 mins

Variable lifetime basics in Rust - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Variable lifetime basics
Declare variable
↓
Variable is valid
↓
Use variable
↓
Scope ends
↓
Variable is dropped
↓
Memory freed
This flow shows how a variable is created, used, and then dropped when its scope ends, freeing memory.
Execution Sample
Rust
fn main() {
    let x = 5;
    println!("x = {}", x);
}
This code declares a variable x, uses it to print, then x is dropped at the end of main.
Execution Table
StepActionVariable x StateOutput
1Declare x = 5x = 5 (valid)
2Print xx = 5 (valid)x = 5
3End of main scopex dropped (invalid)
💡 Variable x is dropped after main ends, memory is freed.
Variable Tracker
VariableStartAfter Step 1After Step 2After Step 3 (End)
xundefined5 (valid)5 (valid)dropped (invalid)
Key Moments - 2 Insights
Why can't we use variable x after step 3?
Because at step 3, the scope ends and x is dropped, so it no longer exists (see execution_table step 3).
Is the variable x valid during the print statement?
Yes, at step 2 x is still valid and holds the value 5, so it can be used safely.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution table, what is the state of x at step 2?
Ax is valid and equals 5
Bx is dropped and invalid
Cx is uninitialized
Dx is zero
💡 Hint
Check the 'Variable x State' column at step 2 in the execution_table.
At which step does variable x get dropped?
AStep 1
BStep 2
CStep 3
DNever
💡 Hint
Look at the 'Action' and 'Variable x State' columns in execution_table for when x becomes invalid.
If we moved the print statement outside main, what would happen?
Ax would still be valid and print 5
BCompilation error because x is out of scope
Cx would print 0 by default
DProgram would crash at runtime
💡 Hint
Variables in Rust are valid only within their scope; see variable_tracker for scope lifetime.
Concept Snapshot
Variable lifetime in Rust:
- Variables are valid within their scope.
- When scope ends, variables are dropped.
- Dropped variables free memory.
- Using variables after drop causes errors.
- Always use variables within their lifetime.
Full Transcript
This visual trace shows how a variable in Rust is declared, used, and then dropped when its scope ends. The variable x is created with value 5, used in a print statement, and then dropped at the end of the main function. After dropping, x no longer exists and cannot be used. This demonstrates Rust's variable lifetime rules: variables live only within their scope and are automatically cleaned up when the scope ends.

Practice

(1/5)
1. What does a variable lifetime in Rust describe?
easy
A. How long a reference remains valid in the program
B. The size of a variable in memory
C. The number of times a variable is used
D. The type of a variable

Solution

  1. Step 1: Define lifetime and evaluate options

    In Rust, lifetime refers to how long a reference is valid and safe to use. Only 'How long a reference remains valid in the program' correctly describes it; B is size, C is usage count, D is type.
  2. Final Answer:

    How long a reference remains valid in the program -> Option A
  3. Quick Check:

    Lifetime = reference validity duration [OK]
Hint: Lifetime means reference validity duration [OK]
Common Mistakes:
  • Confusing lifetime with variable size
  • Thinking lifetime counts usage times
  • Mixing lifetime with variable type
2. Which of the following is the correct syntax to declare a function with a lifetime parameter 'a for a reference argument in Rust?
easy
A. fn example(x: &i32) -> &i32 { x }
B. fn example(x: &i32<'a>) -> &i32<'a> { x }
C. fn example<'a>(x: &'a i32) -> &'a i32 { x }
D. fn example<'a>(x: &i32) -> &'a i32 { x }

Solution

  1. Step 1: Verify lifetime annotation syntax and check options

    Rust requires lifetime parameters declared with 'a before the function and used in references as &'a i32. A correctly declares and uses 'a for input/output. B misplaces after type, C lacks annotations, D misses on input.
  2. Final Answer:

    fn example<'a>(x: &'a i32) -> &'a i32 { x } -> Option C
  3. Quick Check:

    Lifetime syntax = fn name<'a>(x: &'a Type) -> &'a Type [OK]
Hint: Declare lifetime before function, use on references [OK]
Common Mistakes:
  • Placing lifetime after type instead of before
  • Omitting lifetime on input or output references
  • Using lifetime without declaring it
3. What will be the output of this Rust code snippet?
fn main() {
    let mut r;
    {
        let x = 5;
        r = &x;
    }
    println!("{}", r);
}
medium
A. 5
B. Compilation error due to lifetime mismatch
C. 0
D. Runtime panic

Solution

  1. Step 1: Analyze scopes and reference lifetime

    x goes out of scope at end of inner block, but r references it and lives longer, violating Rust's lifetime rules, resulting in compilation error.
  2. Final Answer:

    Compilation error due to lifetime mismatch -> Option B
  3. Quick Check:

    Reference lifetime must not outlive data [OK]
Hint: References can't outlive the data they point to [OK]
Common Mistakes:
  • Assuming code prints 5 without error
  • Expecting runtime panic instead of compile error
  • Ignoring inner block scope
4. Identify the error in this Rust function related to lifetimes:
fn longest(x: &str, y: &str) -> &str {
    if x.len() > y.len() { x } else { y }
}
medium
A. Missing lifetime annotations on parameters and return type
B. Using &str instead of String
C. Function should return usize instead of &str
D. No error, code is correct

Solution

  1. Step 1: Examine function signature and Rust lifetime rules

    The function returns a reference to one of the inputs without lifetime annotations, preventing Rust from verifying safety. Annotations like <'a> are required on params and return.
  2. Final Answer:

    Missing lifetime annotations on parameters and return type -> Option A
  3. Quick Check:

    Return references need lifetime annotations [OK]
Hint: Add lifetime annotations when returning references [OK]
Common Mistakes:
  • Thinking &str vs String causes error
  • Believing function should return length
  • Assuming no error without lifetimes
5. Given this struct and function, which lifetime annotation is correct to ensure the reference inside Holder is valid?
struct Holder<'a> {
    value: &'a str,
}

fn create_holder(s: &str) -> Holder {
    Holder { value: s }
}
hard
A. fn create_holder(s: &'a str) -> Holder<'a> { Holder { value: s } }
B. fn create_holder(s: &str) -> Holder { Holder { value: s } }
C. fn create_holder<'a>(s: &str) -> Holder<'a> { Holder { value: s } }
D. fn create_holder<'a>(s: &'a str) -> Holder<'a> { Holder { value: s } }

Solution

  1. Step 1: Match function signature to struct lifetime parameter

    Holder<'a> ties value's lifetime to 'a. Function must declare 'a, use on s: &'a str, return Holder<'a>. D correct; A lacks fn 'a decl, B/C mismatch lifetimes.
  2. Final Answer:

    fn create_holder<'a>(s: &'a str) -> Holder<'a> { Holder { value: s } } -> Option D
  3. Quick Check:

    Function lifetimes must match struct lifetimes [OK]
Hint: Match function and struct lifetimes exactly [OK]
Common Mistakes:
  • Omitting lifetime on function signature
  • Using lifetime only on return or input, not both
  • Assuming struct lifetime is optional
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