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 is a senior UI engineer at Microsoft.