← 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.
Syntax
rust
let name = value;
let name = new_expression_using(name);

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
// Entry point: execution of the program starts here
fn main() {
    // Declare an immutable variable `x`, set to `5`
    let x = 5;
    // Declare an immutable variable `x`, set to `x + 1`
    let x = x + 1;
    // Declare an immutable variable `x`, set to `x * 2`
    let x = x * 2;
    // Print "x is {}" to the console, substituting in `x` (with a trailing newline)
    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
// Entry point: execution of the program starts here
fn main() {
    // Declare an immutable variable `spaces`, set to `"   "`
    let spaces = "   ";
    // Declare an immutable variable `spaces`, set to `spaces.len()`
    let spaces = spaces.len();
    // Print "Number of spaces: {}" to the console, substituting in `spaces` (with a trailing newline)
    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
// Entry point: execution of the program starts here
fn main() {
    // Declare an immutable variable `x`, set to `1`
    let x = 1;
    {
        // Declare an immutable variable `x`, set to `x + 10`
        let x = x + 10;
        // Print "Inner x: {}" to the console, substituting in `x` (with a trailing newline)
        println!("Inner x: {}", x);
    }
    // Print "Outer x: {}" to the console, substituting in `x` (with a trailing newline)
    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
// Entry point: execution of the program starts here
fn main() {
    // Declare an immutable variable `value`, set to `"42"`
    let value = "42";
    // Declare an immutable variable `value` (an integer), set to `value.parse().unwrap()`
    let value: i32 = value.parse().unwrap();
    // Print "Parsed value: {}" to the console, substituting in `value` (with a trailing newline)
    println!("Parsed value: {}", value);
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
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.