What Is Rust
Rust is a general-purpose, compiled programming language designed for writing fast and reliable software. It gives the control over memory and hardware that C and C++ give, and it prevents whole classes of bugs, such as use-after-free, dangling pointers, and data races, at compile time.
Rust has no garbage collector and no large runtime. Source code is compiled ahead of time into a native executable.
Core Characteristics
| Characteristic | Meaning |
|---|---|
| Compiled | Source code becomes a native machine-code binary before it runs |
| Statically typed | Every value has a type known at compile time |
| Memory safe | Safe code cannot read freed memory, use invalid pointers, or overflow buffers |
| No garbage collector | Memory is freed deterministically when its owner goes out of scope |
| Zero-cost abstractions | High-level features such as iterators and generics compile down to code as fast as hand-written low-level code |
| Fearless concurrency | The compiler rejects data races before the program runs |
| Multi-paradigm | Supports imperative, functional, and trait-based (object-like) styles |
| Expression-based | Most constructs, such as if, match, and blocks, produce a value |
The Three Goals
Rust is built around three goals that older systems languages usually trade against each other.
Safety
/\
/ \
/ \
/ \
/ Rust \
/ \
/____________\
Speed Concurrency
- Safety: invalid memory access is a compile-time error, not a runtime crash.
- Speed: performance is comparable to C and C++.
- Concurrency: shared mutable state across threads is checked by the compiler.
How Rust Achieves Safety Without a Garbage Collector
Rust uses a system of ownership, borrowing, and lifetimes. The compiler checks these rules and then removes them from the final program, so they cost nothing at runtime.
The three rules of ownership:
- Every value has exactly one owner.
- There can be only one owner at a time.
- When the owner goes out of scope, the value is dropped (freed).
let s1 = String::from("hello"); let s2 = s1;
Before the move After the move
s1 s1 (no longer valid)
+----------+ +----------+
| ptr ----+--> "hello" (heap) | moved |
| len = 5 | +----------+
| cap = 5 | s2
+----------+ +----------+
| ptr ----+--> "hello" (heap)
| len = 5 |
| cap = 5 |
+----------+
Using a value after it has been moved is rejected by the compiler:
// ❌ does not compile
fn main() {
let s1 = String::from("hello");
let s2 = s1;
println!("{s1}");
println!("{s2}");
}
error[E0382]: borrow of moved value: `s1`
--> main.rs:4:16
|
2 | let s1 = String::from("hello");
| -- move occurs because `s1` has type `String`, which does not implement the `Copy` trait
3 | let s2 = s1;
| -- value moved here
4 | println!("{s1}");
| ^^ value borrowed here after move
Borrowing lets code use a value through a reference without taking ownership. A value cannot be modified while a reference to it is alive:
// ❌ does not compile
fn main() {
let mut v = vec![1, 2, 3];
let first = &v[0];
v.push(4);
println!("{first}");
}
error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable
--> main.rs:4:5
|
3 | let first = &v[0];
| - immutable borrow occurs here
4 | v.push(4);
| ^^^^^^^^^ mutable borrow occurs here
5 | println!("{first}");
| ----- immutable borrow later used here
v.push(4) may move the vector's data to a new heap allocation, which would leave first pointing at freed memory. Rust stops this at compile time.
What Rust Code Looks Like
fn main() {
let name = "Rust";
let year = 2015;
println!("{name} 1.0 was released in {year}.");
}
Rust 1.0 was released in 2015.
Rust has high-level features such as closures and iterators:
fn main() {
let numbers = vec![1, 2, 3, 4, 5];
let sum: i32 = numbers.iter().sum();
let evens: Vec<i32> = numbers.iter().copied().filter(|n| n % 2 == 0).collect();
println!("sum = {sum}");
println!("evens = {evens:?}");
}
sum = 15
evens = [2, 4]
This compiles to machine code comparable to a hand-written loop.
Safe Rust and Unsafe Rust
Rust has two modes:
| Mode | Description |
|---|---|
| Safe Rust | The default. The compiler guarantees memory safety and freedom from data races |
| Unsafe Rust | Opt-in with the unsafe keyword. Allows raw pointer dereferencing, calling foreign functions, and a few other operations. The programmer is responsible for upholding safety |
unsafe does not turn off the compiler's checks. It unlocks a small set of extra operations. Most Rust programs contain little or no unsafe code, and the standard library wraps unsafe operations in safe interfaces.
The Rust Toolchain
Rust comes with a standard set of tools:
| Tool | Purpose |
|---|---|
rustc |
The compiler |
cargo |
Build system, package manager, and test runner |
rustup |
Installs and manages Rust versions and toolchains |
rustfmt |
Automatic code formatter |
clippy |
Linter that suggests idiomatic improvements |
rustdoc |
Generates HTML documentation from code comments |
rust-analyzer |
Language server for editor support |
| crates.io | The public registry of Rust libraries, called crates |
Where Rust Is Used
| Area | Examples |
|---|---|
| Systems programming | Operating system components, drivers, embedded firmware |
| Command-line tools | ripgrep, bat, fd |
| Web backends and services | HTTP servers, APIs, microservices |
| WebAssembly | Fast code running in the browser |
| Networking and infrastructure | Proxies, databases, cloud tooling |
| Game development | Engines and game logic |
| Embedded systems | Microcontrollers with no operating system |
Language Facts
- Rust 1.0, the first stable release, came out on May 15, 2015.
- The language is open source and developed in the open.
- Rust releases a new stable version every six weeks.
- Backward compatibility is kept for stable code. Breaking changes are introduced only through editions: 2015, 2018, 2021, and 2024.
- The compiler is itself written in Rust.