Variables and mutability
let binds a name to a value. By default that binding is immutable: once set, it cannot change. You opt in to change with let mut. This is the reverse of most languages, and it is deliberate — when you read Rust code, a plain let is a promise that the value stays put, and mut flags exactly the places where it does not.
fn main() {
let name = "Ferris"; // immutable
let mut score = 10; // mutable
println!("{name} starts with {score}");
score += 5;
score = score * 2;
println!("{name} now has {score}");
let level: u8 = 3; // explicit type annotation
println!("level {level}");
}Ferris starts with 10
Ferris now has 30
level 3Remove mut from score and compile. Read the error — it is the one on the card below.
E0384: assigning twice to an immutable variable
fn main() {
let score = 10;
score += 5;
println!("{score}");
}error[E0384]: cannot assign twice to immutable variable `score`
--> main.rs:3:5
|
2 | let score = 10;
| ----- first assignment to `score`
3 | score += 5;
| ^^^^^^^^^^ cannot assign twice to immutable variable
|
help: consider making this binding mutable
|
2 | let mut score = 10;
| +++A binding without mut can be assigned exactly once. The compiler refuses the second assignment rather than letting a value you promised was fixed change behind your back.
If the value really needs to change, declare it let mut. If you only need a new value derived from the old one, shadow it (next lesson).
fn main() {
let mut score = 10;
score += 5;
println!("{score}");
}let. Rust infers score as i32 (the default integer type) from the literal 10. You add an annotation like let level: u8 = 3; when you want a different type or the compiler cannot work it out, which happens most often with parse() and collect().