Lesson 2
Variables & Mutability
Learn about let bindings, mutability with mut, shadowing, and type inference.
Variables Are Immutable by Default
In Rust, when you create a variable with let, it's immutable -- you can't change it. This might feel odd if you're coming from other languages, but it's one of Rust's best features. It prevents accidental changes and makes your code easier to reason about.
If you do need to change a variable, add mut to make it mutable:
let x = 5; // immutable
let mut y = 10; // mutable -- can be changed
y = 20; // this is fine
Shadowing
Rust lets you declare a new variable with the same name using let again. This is called shadowing. The new variable "shadows" the old one. Unlike mut, shadowing lets you change the type too.
Type Inference
Rust is smart about figuring out types. You rarely need to write them explicitly -- the compiler infers them from context. But you can always be explicit with let x: i32 = 5; if you want.
Run the code to see all of this in action.
Try it
fn main() {
// Immutable by default
let name = "Rustacean";
println!("Hello, {}!", name);
// Mutable variables can be changed
let mut score = 0;
println!("Starting score: {}", score);
score = 10;
println!("Updated score: {}", score);
score += 5;
println!("Final score: {}", score);
// Shadowing: re-declare with let
let x = 5;
println!("x is {}", x);
let x = x + 1;
println!("x is now {}", x);
let x = x * 2;
println!("x is now {}", x);
// Shadowing can change the type!
let spaces = " ";
println!("spaces string: '{}'", spaces);
let spaces = spaces.len();
println!("spaces count: {}", spaces);
}Challenge
Create a mutable variable called counter, set it to 1, then change its value to 100 and print both values.
Previous: Hello, Rust!
Next: Data Types