let, mut, and shadowing
Worked examples
Read the claim, then run it and check the machine agrees. One at a time — nothing here is taken on trust.
fn main() {
let limit = 100;
// limit = 120; // <- uncomment: error[E0384] cannot assign twice
// to immutable variable `limit`
let mut count = 0;
count += 1;
count += 1;
println!("count = {count}, limit = {limit}");
}
The commented line is the whole first half of the lesson: put it
back and rustc rejects the program with E0384, names the first
assignment, and suggests let mut limit as the fix. count shows
the honest path — three extra characters and every reader knows
this binding is the moving part.
fn main() {
let reading = " 250 ";
println!("raw: {reading:?}");
let reading = reading.trim();
println!("trimmed: {reading:?}");
let reading: i32 = reading.parse().unwrap_or(0);
println!("parsed: {reading}");
let reading = reading.clamp(0, 100);
println!("clamped: {reading}");
}
Four bindings, one name, zero mut. The third stage is the one
mutation can't do: &str becomes i32. (parse returns a
maybe-failed value; .unwrap_or(0) means "or fall back to 0" —
the full Some/None story is m04's.) After each let, the earlier
stage is unreachable — there is no way to accidentally clamp the
unparsed string.
fn main() {
let x = 5;
{
let x = x * 2;
println!("inner x = {x}");
}
println!("outer x = {x}");
}
Prints inner x = 10, then outer x = 5. The inner let shadows
only inside its braces; when the block ends, the shadow dies and
the original — never mutated, still 5 — is visible again. This is
the proof that shadowing isn't mutation: if it were, the outer
print would say 10.
Check the concept
One question at a time. Unsure? Revisit the lecture, then answer.
The challenge
Pass the quiz to unlock the challenge — your code will still be waiting here.