TypeOfNaN

Mutability and Shadowing in Rust

Nick Scialli
April 19, 2021

Mutability and shadowing are foundational concepts for learning Rust. Let’s review them and their use cases.

Mutability

Mutability is the ability to change a variable. In Rust, variables are immutable by default. In other words, you cannot do the following:

fn main() {
    let age = 25;
    println!("I am {} years old.", age);
    age = 26;
    println!("Now I am {}.", age);
}

The Rust compiler will yell at you when you try to change age to 26 because age is not mutable.

Making a Variable Mutable

There’s a quick fix for this—the mut keyword. We can let the Rust compiler affirmatively know that we plan on mutating age like this:

fn main() {
    let mut age = 25;
    println!("I am {} years old.", age);
    age = 26;
    println!("Now I am {}.", age);
}

And our program now compiles and we get the following output:

I am 25 years old.
Now I am 26.

Shadowing

The idea of shadowing is a bit different. Usually we use shadowing when we want to change the type of a variable. Consider the following code, which will currently not compile:

fn main() {
    let mut age = 9;
    println!("I am {} years old.", age);
    age = "ten";
    println!("Now I am {}.", age);
}

The Rust compiler will not compile the code and will complain that "ten" is not an integer. So even if age is mutable, we’re still not allowed to change its type.

Shadowing a Variable

We can shadow the age variable by reusing the let keyword. In this use case, we don’t even need age to be mutable. Let’s see how this works:

fn main() {
    let age = 9;
    println!("I am {} years old.", age);
    let age = "ten";
    println!("Now I am {}.", age);
}

This now compiles and we see the following output:

I am 9 years old.
Now I am ten.

By shadowing (i.e., reusing the let keyword), we can repurpose our age variable as a string and the compiler is happy.

Nick Scialli

Nick Scialli is a senior UI engineer at Microsoft.

© 2024 Nick Scialli