Variables and Mutability
Variables are immutable by default in Rust. This design choice enforces memory safety and prevents data races in concurrent contexts.
fn main() {
let x = 5;
println!("The value of x is: {x}");
x = 6;
println!("The value of x is: {x}");
}
This produces a compile-time error:
$ cargo run
Compiling variables v0.1.0 (file:///projects/variables)
error[E0384]: cannot assign twice to immutable variable `x`
--> src/main.rs:4:5
|
2 | let x = 5;
| - first assignment to `x`
3 | println!("The value of x is: {x}");
4 | x = 6;
| ^^^^^ cannot assign twice to immutable variable
|
help: consider making this binding mutable
|
2 | let mut x = 5;
| +++
For more information about this error, try `rustc --explain E0384`.
error: could not compile `variables` (bin "variables") due to 1 previous error
To allow mutation, use the mut
keyword:
fn main() { let mut x = 5; println!("The value of x is: {x}"); x = 6; println!("The value of x is: {x}"); }
Constants
Constants differ from immutable variables in several ways:
- Always immutable (no
mut
allowed) - Declared with
const
keyword - Type annotation required
- Must be set to compile-time constant expressions
- Can be declared in any scope, including global
const THREE_HOURS_IN_SECONDS: u32 = 60 * 60 * 3;
Constants use SCREAMING_SNAKE_CASE
by convention and are valid for the entire program duration within their scope.
Shadowing
Rust allows variable shadowing - declaring a new variable with the same name:
fn main() { let x = 5; let x = x + 1; { let x = x * 2; println!("The value of x in the inner scope is: {x}"); } println!("The value of x is: {x}"); }
Output:
$ cargo run
Compiling variables v0.1.0 (file:///projects/variables)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.31s
Running `target/debug/variables`
The value of x in the inner scope is: 12
The value of x is: 6
Shadowing differs from mutation:
- Creates a new variable (enables type changes)
- Requires
let
keyword - Variable remains immutable after transformations
fn main() { let spaces = " "; let spaces = spaces.len(); }
This is invalid with mut
:
fn main() {
let mut spaces = " ";
spaces = spaces.len();
}
Error:
$ cargo run
Compiling variables v0.1.0 (file:///projects/variables)
error[E0308]: mismatched types
--> src/main.rs:3:14
|
2 | let mut spaces = " ";
| ----- expected due to this value
3 | spaces = spaces.len();
| ^^^^^^^^^^^^ expected `&str`, found `usize`
For more information about this error, try `rustc --explain E0308`.
error: could not compile `variables` (bin "variables") due to 1 previous error