๐ Scenario: Imagine you have a small box where you keep a note. You want to understand how long the note stays in the box before it disappears. In Rust, this idea is called variable lifetime. It helps us know when a piece of data is still usable and when it is gone.
๐ฏ Goal: You will create a simple Rust program that shows how a variable's lifetime works. You will declare a variable, use it inside a smaller box (a block), and then try to use it outside to see what happens.
๐ What You'll Learn
Create a variable called message with the value "Hello, Rust!"
Create a new block using curly braces { }
Inside the block, create a variable called inner_message that borrows message
Print inner_message inside the block
Try to print inner_message outside the block (commented out to avoid error)
๐ก Why This Matters
๐ Real World
Understanding variable lifetimes helps prevent bugs related to using data that no longer exists. This is important in programs that manage memory carefully, like games or system tools.
๐ผ Career
Rust developers must understand lifetimes to write safe and efficient code, especially when working with references and borrowing.
Progress0 / 4 steps
1
Create a variable called message
Create a variable called message and set it to the string "Hello, Rust!".
Rust
Hint
Use let message = "Hello, Rust!"; to create the variable.
2
Create a new block and borrow message
Inside the main function, create a new block using { }. Inside this block, create a variable called inner_message that borrows message using &message.
Rust
Hint
Use { } to create a block and let inner_message = &message; to borrow.
3
Print inner_message inside the block
Inside the block where inner_message is declared, add a println! statement to print inner_message.
Rust
Hint
Use println!("{}", inner_message); to print the borrowed message.
4
Try to print inner_message outside the block (commented out)
After the block, add a commented line that tries to print inner_message using println!("{}", inner_message);. This shows that inner_message is not available outside its block.
Rust
Hint
Use // to comment out the line println!("{}", inner_message);.
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
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.
Final Answer:
How long a reference remains valid in the program -> Option A
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
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.
Final Answer:
fn example<'a>(x: &'a i32) -> &'a i32 { x } -> Option C
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
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.
Final Answer:
Compilation error due to lifetime mismatch -> Option B
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
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.
Final Answer:
Missing lifetime annotations on parameters and return type -> Option A
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?
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
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.
Final Answer:
fn create_holder<'a>(s: &'a str) -> Holder<'a> { Holder { value: s } } -> Option D
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 unknownstrongwhile earning +1 Grip toward your certificate.