01 / 035 min read

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 | sh

Follow the prompts (the defaults are correct). Then reload your shell:

source $HOME/.cargo/env

Verify the installation:

rustc --version
cargo --version

You 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_rust

Cargo 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 run

Output:

   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!");
}
  • fn declares a function
  • main is special — it's the entry point of every Rust program
  • println! is a macro (note the !). Macros look like functions but generate code at compile time. You'll use println! 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:

CommandWhat it does
cargo new <name>Create a new project
cargo buildCompile (debug mode)
cargo build --releaseCompile with optimizations
cargo runCompile and run
cargo testRun tests
cargo checkType-check without producing a binary (fast)
cargo add <crate>Add a dependency
cargo doc --openBuild 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.