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.
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.
📋 Quick Reference — Variables
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.