Variables and Types in Rust
Learn about variable bindings, primitive types, mutability, type inference, and type casting in Rust with Docker-ready examples
Rust’s type system is one of its defining features—static, strong, and powerful enough to catch entire classes of bugs at compile time. But it’s also ergonomic: the compiler infers types in most situations, so you don’t have to write type annotations everywhere.
The most important thing to understand about Rust variables is that they are immutable by default. This isn’t just a convention or a linter warning—mutating an immutable binding is a compile error. This design forces you to be intentional about state changes, which makes code easier to reason about and eliminates a common source of bugs.
Rust’s type system reflects its systems-programming heritage: you have precise control over integer widths and signedness, there are two distinct string types with different ownership semantics, and every type conversion must be explicit. The compiler never silently coerces one type into another.
In this tutorial you’ll learn how to declare variables and constants, explore Rust’s primitive types, understand the difference between let and let mut, use type inference and explicit annotations, cast between types, and work with compound types like tuples and arrays.
Bindings, Mutability, and Primitive Types
Rust calls variable declarations bindings because let binds a name to a value. By default, that binding is immutable.
Create a file named variables.rs:
| |
Strings, Shadowing, Type Casting, and Compound Types
Rust has two string types. &str is a string slice—an immutable reference to UTF-8 data stored somewhere (often in the compiled binary). String is a heap-allocated, owned, growable string. This distinction matters because of ownership: a String can be moved and mutated; a &str is just a view.
Shadowing lets you reuse a name in the same scope with a new binding. Unlike mutability, shadowing can change the type of a binding and works with immutable let.
Create a file named variables_types.rs:
| |
Running with Docker
| |
Expected Output
Running variables.rs:
Integer: 5
Float: 3.14
Boolean: true
Char: R
Count: 2
Max points: 100000
i8 max: 127
i64 max: 9223372036854775807
u32 max: 4294967295
Running variables_types.rs:
Hello, Rust!
I own this string
Spaces: 3
i32 as f64: 42
3.99 as i32: 3
Point: (1.5, 2.7)
RGB: (255, 128, 0)
First prime: 2
Array length: 5
Key Concepts
- Immutable by default —
let x = 5creates a binding that cannot be reassigned; uselet mutwhen you need to change a value. This is enforced by the compiler, not just a convention. - Type inference — Rust infers types from context in most situations. You can omit the annotation (
let x = 5) or be explicit (let x: i32 = 5); both are valid and the compiler checks both. - Constants vs. immutable bindings —
constis evaluated at compile time, requires an explicit type, and can be declared in any scope including global. Immutableletbindings are evaluated at runtime and are scoped to their block. - Size-specific integers — Rust offers
i8throughi128andu8throughu128, plusisize/usize(pointer-sized). Choosing the right width is part of systems-level programming; the default integer type isi32. - Two string types —
&stris a borrowed slice (cheap, no allocation);Stringis an owned heap value (flexible, growable). Most string literals are&str; functions that need to modify or own a string useString. - Shadowing changes the binding, not the value —
let spaces = spaces.len()creates a newusizebinding namedspaces, leaving the original&strbinding consumed. This is useful for transforming a value through different types in sequence. - Explicit casts only — Rust never performs implicit numeric coercions. Use
asto cast between numeric types; be aware that casting a float to an integer truncates (it does not round). - Tuples and arrays are fixed-size — Tuples hold heterogeneous types; arrays hold a single type. Both sizes are known at compile time and live on the stack. For dynamically sized collections, use
Vec<T>.
Comments
Loading comments...
Leave a Comment