liveBook · Manning

Shadowing

As explained in Learn Rust in a Month of Lunches

Shadowing is the Rust language feature that creates a new variable with the same name as an existing variable, hiding the earlier binding within the current scope.

Shadowing uses let to create a new variable with the same name as an existing variable. The new binding hides the earlier one, but does not destroy its value. Shadowing resembles mutability, yet it creates a different variable rather than changing the original. section 1.11 section 1.12

fn main() {
    let my_number = 8;           #1
    println!("{}", my_number);
    let my_number = 9.2;         #2
    println!("{}", my_number);
}

This minimal example binds my_number first to an integer and then shadows it with a floating-point value. section 1.11

Bindings follow scopes, the regions enclosed by braces. Within one scope, the newest binding is visible. A binding created inside a nested scope hides the outer binding only until that inner scope ends; afterward, the outer binding is visible again. section 1.11 section 1.12

fn main() {
    let my_number = 8;
    println!("{}", my_number);
    {
        let my_number = 9.2;
        println!("{}", my_number);    #1
    }
    println!("{}", my_number);        #2
}

The inner my_number is visible inside its block, while the original binding becomes visible again after the block closes. section 1.11

Shadowing is useful when:

  • A sequence of transformations makes intermediate names unnecessary, allowing one meaningful name to represent each successive value. section 1.11
  • A value needs a new type, such as converting an integer binding into a floating-point binding. section 1.11
  • A final expression returns the latest binding from a block, such as a value built through multiplication and addition. section 1.11
fn main() {
    let country = String::from("Austria");
    let country_ref = &country;
    let country = 8;
    println!("{country_ref} {country}");
}

A reference can continue pointing to the original String after country is shadowed by the integer 8, demonstrating that shadowing does not destroy the earlier value. section 2.6

Remember the distinction: mutability changes a binding's value, while shadowing creates a new binding that blocks the old name. The earlier value can remain available through another reference or after an inner scope ends. section 1.11 section 2.6

How Learn Rust in a Month of Lunches covers it

How deep it goes
Defines bindings, scopes, mutability differences, and references, but stops short of deeper ownership mechanics.
Examples
Demonstrates integer-to-float rebinding, nested blocks, arithmetic transformations, and a reference surviving shadowing.
What it assumes
Assumes variables, let bindings, mutability, code blocks, and basic types while introducing scopes and references.
What you can do after
Apply shadowing in Rust to reuse clear names, transform values, and distinguish hidden bindings from mutable ones.
How it connects
Connects shadowing with mutability, scopes, references, ownership, and type conversion.

Also explained in

Compare how 4 books explain shadowing →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Learn Rust in a Month of Lunches. The section links point to the parts of the book it draws on.