Introduction to Rust
Why Rust exists, what makes it different from other systems languages, how to install it, and your first program.
Why Rust?
Every systems programming language makes a tradeoff between control and safety. C and C++ give you full control — manual memory management, direct pointer arithmetic, zero-overhead abstractions — but at the cost of an entire class of bugs: use-after-free, double-free, buffer overflows, data races. These are not edge cases. They account for roughly 70% of CVEs in large C/C++ codebases (Microsoft, Google, and Mozilla have all published studies confirming this).
Garbage-collected languages (Go, Java, Python) eliminate memory bugs by removing manual control. You trade raw performance and deterministic latency for safety. For most applications, this is the right call. For systems code — operating systems, databases, embedded firmware, game engines, network proxies — it isn't.
Rust's bet: you can have both. Memory safety without a garbage collector, enforced at compile time by the type system. If your code compiles, an entire class of bugs cannot exist at runtime.
This is not a small claim. Rust delivers on it through a concept called ownership, which is the core idea the entire language is built around. You'll spend the first few articles understanding it.
What Rust Is Good At
- Systems programming — OS kernels, device drivers, embedded systems
- High-performance services — web servers, proxies, databases, game servers
- WebAssembly — Rust is the most popular language compiled to Wasm
- CLI tools — fast startup, single binary, no runtime dependency
- Anywhere C/C++ is used today — but with safety guarantees
What Rust Is Harder At
- Rapid prototyping — the compiler is strict; it slows you down until you understand ownership
- Dynamic, loosely-typed domains — scripting, data science, glue code
- Large teams new to systems programming — the learning curve is real
Rust is not the right tool for every job. It's the right tool when performance, safety, and control all matter simultaneously.
Installing Rust
Rust is installed via rustup, the official toolchain manager. It installs the compiler (rustc), the build tool and package manager (cargo), and the standard library.
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | shFollow the prompts (the defaults are correct). Then reload your shell:
source $HOME/.cargo/envVerify the installation:
rustc --version
cargo --versionYou should see version numbers like rustc 1.78.0 and cargo 1.78.0. Rust releases a new stable version every six weeks.
Your First Program
Create a new project with Cargo:
cargo new hello_rust
cd hello_rustCargo creates this structure:
hello_rust/
├── Cargo.toml # project manifest (name, version, dependencies)
└── src/
└── main.rs # entry point
Open src/main.rs:
fn main() {
println!("Hello, world!");
}Run it:
cargo runOutput:
Compiling hello_rust v0.1.0
Finished dev [unoptimized + debuginfo] target(s) in 0.42s
Running `target/debug/hello_rust`
Hello, world!
cargo run compiles and runs in one step. Use cargo build to compile only, and cargo build --release for an optimized production binary.
Understanding the Code
fn main() {
println!("Hello, world!");
}fndeclares a functionmainis special — it's the entry point of every Rust programprintln!is a macro (note the!). Macros look like functions but generate code at compile time. You'll useprintln!constantly; you'll write your own macros much later.- Statements end with
; - Blocks are delimited by
{}
Cargo: The Build System and Package Manager
Cargo does what make + npm/pip do together in other ecosystems:
| Command | What it does |
|---|---|
cargo new <name> | Create a new project |
cargo build | Compile (debug mode) |
cargo build --release | Compile with optimizations |
cargo run | Compile and run |
cargo test | Run tests |
cargo check | Type-check without producing a binary (fast) |
cargo add <crate> | Add a dependency |
cargo doc --open | Build and open documentation |
Dependencies are declared in Cargo.toml:
[dependencies]
serde = { version = "1.0", features = ["derive"] }
tokio = { version = "1", features = ["full"] }Running cargo build fetches, compiles, and links them automatically. No manual downloading, no header files, no linker flags.
The Rust package ecosystem lives at crates.io. As of 2025, it hosts over 140,000 crates.
The Rust Compiler Is Your Friend
Coming from C/C++, you might expect a compiler that passes things through and lets bugs manifest at runtime. Rust's compiler is different — it is aggressively strict, and its error messages are designed to teach you.
If you write this:
fn main() {
let x = 5;
x = 6; // error: cannot assign twice to immutable variable
}The compiler gives you:
error[E0384]: cannot assign twice to immutable variable `x`
--> src/main.rs:3:5
|
2 | let x = 5;
| -
| |
| first assignment to `x`
| help: consider making this binding mutable: `mut x`
3 | x = 6;
| ^^^^^ cannot assign twice to immutable variable
It tells you exactly what went wrong, where, and often how to fix it. This is intentional. The Rust team considers error messages a first-class feature of the language.
What's Next
The next article covers variables and mutability — Rust's first surprise for developers coming from other languages, and the foundation for understanding why ownership works the way it does.