Variable shadowing in Rust - Time & Space Complexity
Let's explore how variable shadowing affects the time it takes for a program to run.
We want to see if creating new variables with the same name changes how long the code takes as input grows.
Analyze the time complexity of the following code snippet.
fn sum_numbers(numbers: &[i32]) -> i32 {
let mut sum = 0;
for &num in numbers {
let sum = sum + num; // shadowing sum
}
sum
}
This code tries to add all numbers in a list, but it uses variable shadowing inside the loop.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Looping through each number in the list.
- How many times: Once for every number in the input list.
Each number in the list is processed once, even with shadowing.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 10 additions |
| 100 | 100 additions |
| 1000 | 1000 additions |
Pattern observation: The work grows directly with the number of items; shadowing does not add extra loops.
Time Complexity: O(n)
This means the time to run grows in a straight line with the size of the input list, regardless of shadowing.
[X] Wrong: "Variable shadowing makes the code slower because it creates new variables each time."
[OK] Correct: Shadowing just reuses the name but does not add extra loops or repeated work; it does not increase the number of operations.
Understanding how variable shadowing affects performance shows you can separate naming from actual work done, a useful skill in coding and interviews.
"What if the shadowed variable was used to call a function inside the loop? How would that affect the time complexity?"
Practice
Solution
Step 1: Understand variable shadowing concept
Variable shadowing means declaring a new variable with the same name as an existing one, which replaces the old variable in the current scope.Step 2: Identify what shadowing allows
This lets you reuse the same name to update the value or even change the type without needing a new variable name.Final Answer:
Reuse the same variable name to store a new value or type -> Option CQuick Check:
Shadowing = reuse variable name [OK]
- Thinking shadowing creates global variables
- Confusing shadowing with immutability
- Assuming shadowing changes variable type automatically
Solution
Step 1: Check for correct shadowing syntax
Shadowing usesletagain with the same variable name to create a new variable that hides the old one.Step 2: Analyze each option
let x = 5; let x = x + 1; println!("{}", x);:let x = 5; let x = x + 1; println!("{}", x);valid shadowing using previous value. let x = 5; x = x + 1; println!("{}", x);:let x = 5; x = x + 1; ...reassignment to immutable, compile error. let mut x = 5; x = x + 1; println!("{}", x);:let mut x = 5; x = x + 1; ...valid mutation but no shadowing (missing secondlet). let x = 5; mut x = 6; println!("{}", x);:let x = 5; mut x = 6; ...invalid syntax,mutrequireslet.Final Answer:
let x = 5; let x = x + 1; println!("{}", x); -> Option AQuick Check:
Shadowing requiresletagain [OK]
- Trying to reassign immutable variables without 'mut'
- Confusing shadowing with mutable reassignment
- Using 'mut' incorrectly with shadowing
let x = 10;
let x = x * 2;
let x = "Value: ".to_string() + &x.to_string();
println!("{}", x);Solution
Step 1: Follow variable shadowing and type changes
First,xis 10 (integer). Then shadowed to 20 (integer). Then shadowed again to a String "Value: 20" by concatenating strings.Step 2: Understand the final print output
The lastxis a String "Value: 20", so printing it outputs exactly that.Final Answer:
Value: 20 -> Option DQuick Check:
Shadowing can change type; final value is string [OK]
- Assuming variable type cannot change with shadowing
- Expecting numeric output instead of string
- Confusing variable name with literal output
let x = 5;
let x = x + 1;
let mut x = x * 2;
x = 10;
println!("{}", x);Solution
Step 1: Analyze shadowing and mutability
Firstxis immutable 5, then shadowed to 6 (immutable), then shadowed to mutable 12.Step 2: Check assignment and print
Since the lastxis mutable, assigningx = 10;is valid. Printing outputs 10.Final Answer:
No error; code runs and prints 10 -> Option BQuick Check:
Shadowing can add mutability; assignment allowed [OK]
- Thinking mutability cannot be added by shadowing
- Confusing shadowing with reassignment rules
- Assuming type must stay the same when shadowing
result?let x = 3;
let x = x + 2;
{
let x = x * 2;
let x = "Number: ".to_string() + &x.to_string();
println!("{}", x);
}
let result = x + 1;
println!("{}", result);Solution
Step 1: Track shadowing in outer and inner scopes
Outside the block,xis first 3, then shadowed to 5. Inside the block,xshadows to 10 (5*2), then to a String "Number: 10". This inner shadowing does not affect outerx.Step 2: Calculate final result outside the block
Outside,xremains 5, soresult = x + 1 = 6. The print inside the block shows "Number: 10" but does not change outerx.Final Answer:
6 -> Option AQuick Check:
Inner shadowing does not affect outer variable [OK]
- Assuming inner shadowing changes outer variable
- Confusing printed output with variable value
- Expecting type change to persist outside inner scope
Ready to prove it?
Pass the test and this pattern moves unknown
