Immutability by Default
In Rust, variables are immutable by default. This is a deliberate design choice that helps prevent bugs. Use mut to make a variable mutable:
let x = 5; // immutable
// x = 6; // ❌ compile error!
let mut y = 5; // mutable
y = 6; // ✅ ok
println!("{}", y); // 6
Constants
const MAX_POINTS: u32 = 100_000;
const PI: f64 = 3.14159265358979;
// Constants are always immutable, must have a type annotation
// and can be declared in any scope
Shadowing
You can declare a new variable with the same name as a previous one — the new variable shadows the old one:
let x = 5;
let x = x + 1; // shadows previous x
let x = x * 2; // shadows again
println!("{}", x); // 12
// Shadowing allows changing type!
let spaces = " "; // &str
let spaces = spaces.len(); // usize
Scalar Types
let i: i32 = -42; // signed integer (i8, i16, i32, i64, i128)
let u: u64 = 1_000_000; // unsigned integer (u8, u16, u32, u64, u128)
let f: f64 = 3.14; // floating point (f32, f64)
let b: bool = true; // boolean
let c: char = 'Z'; // character (4 bytes, Unicode scalar)
Compound Types
// Tuple — fixed size, can mix types
let tup: (i32, f64, bool) = (500, 6.4, true);
let (x, y, z) = tup; // destructuring
println!("{}", tup.0); // access by index: 500
// Array — fixed size, same type
let arr: [i32; 5] = [1, 2, 3, 4, 5];
println!("{}", arr[0]); // 1
let zeros = [0; 3]; // [0, 0, 0]