Variables & Mutability
Rust is a systems programming language focused on speed, memory safety, and fearless concurrency — and one of its core safety choices is that variables are immutable by default.
Learn Variables & Mutability in our free Rust course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick reference.
Part of the free Rust course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
In this lesson you'll learn how to declare variables with let , opt in to change with mut , define compile-time constants, and reuse names through shadowing.
What You'll Learn in This Lesson
1️⃣ Immutable by Default, Mutable on Request
When you write let x = 5; , Rust binds the value 5 to the name x and locks it: trying to assign a new value later is a compile error. This is the opposite of most languages, and it's deliberate — it stops values from changing behind your back. When a value genuinely needs to change, you add mut to say so out loud.
The key idea: immutability is the safe default, and mut is how you opt out of it for a specific variable. Anyone reading your code can see at a glance which variables are allowed to change.
2️⃣ Constants and Shadowing
A constant is a value that is fixed for the whole program and known at compile time. Unlike a normal let binding, it always needs a type annotation and can never be made mutable. Shadowing is a separate idea: you can use let again with the same name to create a new variable, even one with a different type. Read the comments closely.
Shadowing shines when you transform a value: notice how spaces went from a string to its length (a number) while keeping the same friendly name. With mut alone you couldn't change the type like that.
Your turn. Fill in the blanks marked ___ , then run it.
Mini-Challenge: A Temperature Tracker
Write it yourself from the outline, run it with cargo run , and check your output against the example. You'll combine mut and shadowing in one short program.
Common Errors (and the fix)
- "cannot assign twice to immutable variable" — You tried to reassign a variable declared without mut . Add mut : let mut x = 5; .
- "missing type for item" — Constants always need a type. Write const MAX: u32 = 100; , not const MAX = 100; .
- "mismatched types" after reassigning — With mut the type can't change. To change the type, use shadowing ( let again) instead of plain assignment.
- Expecting mut to change the type — mut only allows new values of the same type. Shadowing is what lets you switch types under the same name.
Pro Tips
- 💡 Default to immutable: only add mut when the compiler complains that you need it. Less mutable state means fewer bugs.
- 💡 Use shadowing for conversions: turning user input text into a number is the classic case — reuse the name with a new let .
- 💡 Name constants loudly: SCREAMING_SNAKE_CASE makes constants stand out from ordinary variables.
📋 Quick Reference — Variables
Goal
Rust Syntax
Immutable variable
let x = 5;
Mutable variable
let mut x = 5;
Reassign (needs mut)
x = 6;
Constant
const MAX: u32 = 100;
Shadowing
let x = x + 1;
Frequently Asked Questions
🎉 Lesson Complete!
- ✅ Variables are declared with let and are immutable by default
- ✅ Add mut to allow a variable to change
- ✅ const declares a compile-time constant and always needs a type
- ✅ Shadowing reuses a name with a new let — and can change the type
- ✅ Next lesson: Data Types — integers, floats, booleans, tuples, and arrays
Practice quiz
Are Rust variables mutable or immutable by default?
- Mutable
- It depends on the type
- Immutable
- Always constant
Answer: Immutable. Variables are immutable by default; you opt into change with mut.
Which keyword makes a variable able to change?
- mut
- var
- let
- const
Answer: mut. Adding mut, as in let mut x = 5;, allows reassignment.
What error does reassigning an immutable variable produce?
- type mismatch
- missing semicolon
- no such variable
- cannot assign twice to immutable variable
Answer: cannot assign twice to immutable variable. Reassigning a non-mut variable gives 'cannot assign twice to immutable variable'.
What does shadowing do?
- Mutates the same variable
- Creates a new variable that reuses the name
- Deletes the variable
- Makes it global
Answer: Creates a new variable that reuses the name. Shadowing uses let again to create a brand-new variable with the same name.
Can shadowing change a variable's type?
- Yes
- No, never
- Only for numbers
- Only with mut
Answer: Yes. Because shadowing makes a new variable, it can have a different type.
Can a variable marked mut change its type on reassignment?
- Yes
- Only to a larger type
- No, the type must stay the same
- Only once
Answer: No, the type must stay the same. mut allows new values of the same type; to change type you shadow.
Which keyword declares a compile-time constant?
- let
- const
- mut
- static let
Answer: const. const declares a constant that is fixed at compile time.
Do constants require a type annotation?
- No, it is optional
- Only for integers
- Only inside functions
- Yes, always
Answer: Yes, always. Constants always need an explicit type, like const MAX: u32 = 100;.
What naming convention do constants use by convention?
- camelCase
- SCREAMING_SNAKE_CASE
- snake_case
- PascalCase
Answer: SCREAMING_SNAKE_CASE. Constants are conventionally named in SCREAMING_SNAKE_CASE.
What do underscores in a number like 100_000 do?
- Multiply the value
- Mark it as a float
- Act as visual separators with no effect
- Cause a compile error
Answer: Act as visual separators with no effect. Underscores are ignored separators; 100_000 equals 100000.
Continue this course
- Previous: Introduction to Rust
- Next: Data Types