← Back to Rust Course | Chapter 2: Variables & Types | Lesson 4 of 7

Variable Shadowing

Shadowing lets you reuse the same name for a new value, kind of like writing over an old note with a new one.

Basic Shadowing

Using let again with a name that already exists creates a brand new variable that shadows (hides) the old one. The old value still existed, but it is no longer accessible under that name.

Example: Basic Shadowing

markup
fn main() {
    let x = 5;
    let x = x + 1;
    let x = x * 2;
    println!("x is {}", x);
}

Shadowing Can Change Type

Because shadowing creates a completely new variable, the new binding is free to have a different type than the original, which plain mutation with mut never allows.

Example: Shadowing Can Change Type

markup
fn main() {
    let spaces = "   ";
    let spaces = spaces.len();
    println!("Number of spaces: {}", spaces);
}

Shadowing Within a Block

A shadowed variable inside an inner block only shadows the outer one for the duration of that block. Once the block ends, the outer variable's value is visible again.

Example: Shadowing Within a Block

markup
fn main() {
    let x = 1;
    {
        let x = x + 10;
        println!("Inner x: {}", x);
    }
    println!("Outer x: {}", x);
}

Shadowing vs Mutability

Shadowing and mut solve different problems: mut changes a value in place while keeping the same type, whereas shadowing produces an independent new binding, optionally with a new type, without ever needing mut.

Example: Shadowing vs Mutability

markup
fn main() {
    let value = "42";
    let value: i32 = value.parse().unwrap();
    println!("Parsed value: {}", value);
}
Common Mistakes
  1. Confusing shadowing with mutation -- shadowing creates an entirely new variable, it does not change the old one in place.
  2. Thinking shadowing requires mut; in fact shadowing works with plain immutable let bindings.
  3. Overusing shadowing to change a variable's type repeatedly in a way that makes code confusing to follow.
Chapter Summary
  • Shadowing declares a new variable with let that reuses an existing name, hiding the previous one.
  • Shadowing can change the type of the value stored under that name, unlike mutation.
  • Each shadowed variable exists until the end of its scope or until shadowed again.
  • Shadowing is useful for transforming a value step by step while keeping a meaningful name.
🔒

Chapter Quiz — Complete all 7 topics to unlock

0/7 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.