Rust Variables, Mutability, and Shadowing

Bindings are immutable by default; mut and shadowing change that.

Rust
fn main() {
    let mut count = 1;
    count += 2;
    let count = count * 10;
    println!("{}", count);
}
Output
30

Explanation

In Rust a let binding cannot be reassigned unless it is declared mut. Starting from immutable removes a whole class of accidental changes, and the compiler enforces it.

Shadowing declares a new binding with the same name using let again. It can even change the type, and the new binding is itself immutable. Here count is first changed in place to 3, and then a new count is created as 3 * 10.

Explore the dry run
Guided walkthroughReady
1fn main() {
2 let mut count = 1;
3 count += 2;
4 let count = count * 10;
5 println!("{}", count);
6}

Follow the example

Start to inspect the source, values, and output. These prepared steps explain the published sample; grouped loop steps describe multiple iterations.

View the complete dry-run table
Prepared trace of the published program. Some rows group repeated iterations.
Step / lineWhat happensState after stepOutput so far
A mutable binding starting at 1.count = 1
—
Mutate it in place.count = 3
—
Shadow it with a new immutable binding.count = 30
—
Print the latest binding.count = 30
30

Cost and common mistakes

O(1) time and space.

  • Removing mut from the first line makes count += 2 a compile error.
  • Shadowing creates a new variable; it is not the same as mutating the old one.

Try it yourself

Predict the output if the last arithmetic line were let count = count + 1;

Reveal answer and reasoning

count is 3 before it, so the new binding is 4 and it prints 4.

Further reading