Rust Variables Explained: mut, const, Shadowing and Data Types
November 10, 2026
Welcome to episode 3 of Rust for Beginners, a series for complete beginners (no programming experience needed). In the last video, we used Cargo to build and run a dice roller. Today, we'll learn about variables and data types in Rust. Every code block below is the exact code from the video, ready to copy.
- All episodes are in the Rust Tutorial for Beginners playlist.
- Versions used: Rust 1.99.1 on Ubuntu, VS Code with rust-analyzer.
1. New project
Let's start a new project called variables, and open it in VS Code.
cargo new variables
cd variables2. let
We create a variable with the let keyword. Here, score holds the number ten, and we print it inside curly braces.
src/main.rs:
Typed first without mut ; mut is added in step 6.
fn main() {
let mut score = 10;
println!("Score: {score}");
score = 20;
println!("Score: {score}");
}Output: Score: 10 / Score: 20
3. Change it
Now let's try to change the score to twenty, and run it.
cargo run4. Immutable error
Rust refuses! Variables in Rust are immutable by default. Once a value is set, it cannot change. This prevents many bugs.
5. mut
The compiler even tells us the fix: add the mut keyword to make the variable mutable.
6. It works
Now it runs, and the score changes from ten to twenty.
cargo run7. Constants
For values that never change, use a constant. Constants are written in capital letters, and they always need a type.
const MAX_LEVEL: u32 = 100;
fn main() {
println!("Max level: {MAX_LEVEL}");
let spaces = " ";
let spaces = spaces.len();
println!("Spaces: {spaces}");
}Output: Max level: 100 / Spaces: 3
8. Shadowing
Rust also allows shadowing: we declare a new variable with the same name. Here, spaces starts as text, and becomes a number, its length.
9. Run B
Let's run it.
cargo run10. Data types
Every value in Rust has a type. Usually, the compiler figures it out, but we can also write the type after a colon.
fn main() {
let temperature: i32 = -5;
let age: u8 = 30;
let price: f64 = 9.99;
let is_ready: bool = true;
let letter: char = 'R';
println!("{temperature} {age} {price} {is_ready} {letter}");
let point: (i32, f64) = (3, 4.5);
let days = ["Mon", "Tue", "Wed"];
println!("x = {}, y = {}", point.0, point.1);
println!("First day: {}", days[0]);
}Output: -5 30 9.99 true R / x = 3, y = 4.5 / First day: Mon
11. Integers
i thirty-two is a signed integer, so it can be negative. It's the default for whole numbers. u eight is unsigned, from zero to two hundred fifty-five.
12. Out of range
What if we put three hundred into a u eight?
cargo run13. Range error
The compiler catches it before the program even runs. Let's change it back.
14. Float, bool, char
f sixty-four holds decimal numbers, bool is true or false, and char holds a single character in single quotes.
15. Tuple and array
Two compound types group values together. A tuple can mix types, and we read it with dot zero and dot one. An array holds values of one type, and we read it by index, starting from zero.
16. Run C
Let's run it.
cargo runRecap
To recap: the let keyword creates a variable, mut makes it changeable, const makes a constant, shadowing reuses a name, and every value has a type.