Assigning a new value
A variable can hold a different value later in the program. You change it with the assignment operator, =, and no let. In Rust there is one condition: the variable has to be declared with let mut.
// Initializing with 5:
let mut my_var = 5;
// Assigning the value 10:
my_var = 10;
println!("{}", my_var); // Output: 10
The first line creates my_var and starts it at 5. The assignment replaces that value with 10. From then on, every use of my_var sees 10, and the old value is gone.
Why mut is required
In Rust, a plain let binding can't be assigned to a second time. Mutability is something you opt into. Without mut, this program doesn't compile:
let my_var = 5;
my_var = 10;
The compiler reports error[E0384]: cannot assign twice to immutable variable `my_var` and points at the declaration with the help text consider making this binding mutable. The fix is to write let mut my_var = 5;.
The reasoning is that a reader can trust a plain let: the value never changes, so there is nothing to track. When you see mut, you know the value may change further down.
Assigning one variable to another
The right side of = can be any expression, including another variable:
let mut my_var = 5;
let my_num = 10;
my_var = my_num;
println!("{}", my_var); // Output: 10
The value held by my_num, which is 10, is copied into my_var. Only my_var had to be mut, because only my_var receives a new value. The variable on the right is just read, so it can stay immutable.
The new value can also depend on the old one. The right side is worked out first, then stored:
let mut x = 1;
x = x + 1;
x += 1;
println!("{}", x); // Output: 3
Here x += 1 is a shorter way to write x = x + 1.
The type stays the same
Reassignment changes the value, never the type. A variable that started as an integer can only receive integers:
let mut my_var = 5;
my_var = "ten";
This fails with error[E0308]: mismatched types and expected integer, found `&str`. To change the type as well, you would declare a new variable with let, which is a different technique called shadowing.
Solving the exercise
The program tells a short story about a developer, first today and then ten years later. All three variables are declared with let mut:
let mut role = "Junior Developer";
let mut age = 24;
let mut language = "Java";
The first three println! lines print today's facts, and the last three print the facts again after ten years. Between them, you write the code that moves the story forward:
- Update
role. He is a Senior Developer now:role = "Senior Developer";. - Update
age. Ten years older than24is34:age = 34;. - Leave
languagealone. The story says he never changed it, so the last line must still printJava.
Neither assignment starts with let. Writing let age = 34; would create a second, new variable that hides the first, and that is not the same as changing the existing one. Plain = changes the original.
let mut role = "Junior Developer";
let mut age = 24;
let mut language = "Java";
// Today
println!("His age is {}", age);
println!("He is a {}", role);
println!("He codes in {}", language);
// ---------------------------------------
// Write your code here:
role = "Senior Developer";
age = 34;
// ---------------------------------------
// Ten years later:
println!("Ten years later, his age is {}", age);
println!("He is a {}", role);
println!("He still codes in {}", language);
The output is:
His age is 24
He is a Junior Developer
He codes in Java
Ten years later, his age is 34
He is a Senior Developer
He still codes in Java
Common mistakes
- Forgetting
mut. The error message includes the fix, so read it before searching elsewhere. - Adding
letto an assignment. It compiles, but it declares a new variable that hides the old one instead of updating it. Inside an inner block such as anifbody, the new variable ends at the closing brace, and the original keeps its old value afterwards. - Changing a variable the story says must stay. Reassign only what the task names; every extra assignment is a chance to print a wrong value.
What the compiler warns about
The compiler also checks that mut is really needed. In this program language is declared with mut but never reassigned, so the compiler adds warning: variable does not need to be mutable and suggests removing it. The code still works, because a warning doesn't stop it. In your own programs, give mut only to the variables that really change.
A related warning is value assigned to `my_var` is never read. It appears when you store a value and overwrite it before anything reads it, which usually means a leftover line.
Key takeaways
- Reassign with
=, withoutlet. - The variable must be declared with
let mut, otherwise the compiler reportscannot assign twice to immutable variable. - The right side can be a value, another variable or an expression that uses the variable itself.
- The new value must have the same type as the old one.
- Use
mutonly where a value really changes.
