Free Handbook · Every example compiled & verified

Rust Handbook

Learn Rust the way it is written at work. Seventeen modules from your first program to a job: every example program was compiled with rustc and run before publishing, with its output shown exactly as it printed, and the real compiler errors you will hit (E0382, E0499, E0502, E0106 and more) are explained with the fix. Variables and types, flow control and functions, ownership and borrowing, structs, enums and pattern matching, collections and strings, Result, Option and the ? operator, traits and generics, lifetimes, closures and iterators, smart pointers, threads and channels, debugging, Rust with Cargo, tokio, axum, serde, sqlx, Redis, Kafka, AWS, Docker and GitHub Actions, data structures and algorithms, problem-solving patterns, interview questions, a certification exam, and a resume check at the end.

0 / 140 lessons🔥 0 day streak
ShareXLinkedIn

How this handbook works

Every lesson has a complete Rust program with the exact output it prints — each one compiled and run with the real Rust toolchain before it was published, so what you see is what you will get when you run it yourself — a trace of what the program did line by line where that matters, and the real compiler or runtime error you will hit next, with why it happened and the fix. Lessons tick themselves as you go. Finish the handbook, sit the exam, get the certificate, then take your resume through the ATS checker against a real job posting.

17modules
140lessons
124compiled examples
75real errors explained

Module 00 · what you'll be able to do

  • Explain what makes Rust different: memory safety checked at compile time, with no garbage collector
  • Install Rust with rustup on macOS, Linux or Windows and check the toolchain works
  • Create, build and run a project with cargo new, cargo run and cargo build --release
  • Read the parts of a Rust program: fn main, macros like println!, statements and comments
  • Know how this handbook works: every example is compiled with the real rustc and its output is exact
01

Why Rust

Rust is a compiled systems programming language that gives you the speed and low-level control of C and C++ without their memory bugs. Programs written in C crash, leak or get hacked because of use-after-free, double-free, dangling pointers and data races. Rust rules those out at compile time: a set of checks called the borrow checker refuses to build a program that could touch freed memory or let two threads write the same data at once.

The other half of the trick is what Rust does not have: a garbage collector. Java, Go, C# and Python pause now and then to find memory nobody uses any more. Rust knows at compile time exactly where each value stops being used and frees it there — the idea is called ownership, and it is what Module 03 is about. You get predictable performance with no pauses and no runtime to ship.

  • Memory safety without a GC — no null pointer dereferences, no use-after-free, no data races in safe code.
  • Fast — compiles to native machine code through LLVM; performance is in the same league as C and C++.
  • Errors are values — no exceptions and no null; missing values are Option, failures are Result, and the compiler makes you handle both.
  • Tooling that just works — cargo builds, tests, formats, lints and fetches libraries (crates) with one command each.
  • Helpful compiler — its error messages point at the exact line, explain the rule you broke and usually suggest the fix.
Where Rust is usedExamples of what gets built
Systems and infrastructureParts of the Linux kernel and Windows, container runtimes, databases, storage engines
Cloud and networkingProxies, load balancers, serverless runtimes, high-throughput web services
Command-line toolsripgrep, fd, bat — fast, single-binary tools
WebAssemblyPerformance-critical code that runs in the browser
Data and developer toolingQuery engines, dataframe libraries, JavaScript bundlers and linters, Python package managers
EmbeddedFirmware for microcontrollers, where there is no operating system and no room for a GC
In real jobs
Rust job listings cluster around infrastructure, cloud platforms, databases, security, blockchain and developer tools. Teams pick it when a C++ service keeps crashing or a Go/Java service needs lower, steadier latency. The learning curve is steeper than Python or Go — mostly the borrow checker — which is also why people who get past it are in demand.
A short history
Rust started as a personal project by Graydon Hoare at Mozilla, reached 1.0 in 2015, and is now run by the independent Rust Foundation. A new stable version ships every six weeks, and code written for 1.0 still compiles. Large language changes are grouped into editions (2015, 2018, 2021, 2024); this handbook uses the 2021 edition.
02

Install Rust with rustup

The official way to install Rust is rustup, a small installer that manages Rust versions for you. It installs three tools you will use every day: rustc (the compiler), cargo (the build tool and package manager) and rustup itself (for updates).

macOS and Linux

bash
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# choose option 1 (default install), then open a new terminal, or:
source "$HOME/.cargo/env"

On macOS, Rust also needs a linker from the Xcode command line tools: run xcode-select --install if the build later says "linker cc not found".

Windows

bash
# Option A: download and run rustup-init.exe from https://rustup.rs
# Option B: with winget
winget install Rustlang.Rustup

rustup-init asks to install the Visual Studio C++ Build Tools if they are missing — say yes; Rust uses the Microsoft linker on Windows.

Check it worked

bash
rustc --version     # rustc 1.xx.x (...)
cargo --version     # cargo 1.xx.x (...)
rustup update       # later: upgrade to the newest stable release
Editor setup
Install VS Code with the rust-analyzer extension (or use RustRover). rust-analyzer shows types inline, underlines borrow-checker errors as you type, and runs cargo check on save. It makes the early weeks much easier.
03

Your first Rust program

Every Rust program starts at a function called main. Save this as main.rs:

rustmain.rs
fn main() {
    println!("Hello, world!");
    println!("I am learning Rust.");
}
Outputcompiled & run with real Rust
Hello, world!
I am learning Rust.
Your turn

Add a third line that prints your name. Remember the semicolon at the end of each statement.

The fastest way to compile a single file is rustc directly. It produces a native executable next to the source — there is no virtual machine and nothing to install on the machine that runs it.

bash
rustc main.rs     # compile: creates ./main (main.exe on Windows)
./main            # run it
Hello, world!
I am learning Rust.
VisualizeWhat happens when ./main runsStep 1 / 4
fn main() {
println!("Hello, world!");
println!("I am learning Rust.");
}
Line 1

The operating system starts the program, and Rust calls main. It takes no arguments and returns nothing.

Variables now

nothing yet

All 4 steps as a table
StepLineWhat happenedVariables now
11The operating system starts the program, and Rust calls main. It takes no arguments and returns nothing.
22println! writes the text plus a newline to standard output. The ! means it is a macro, not a function.
33The second statement runs.
44main ends, so the program exits with status 0 (success).
Error you will hit

Forgetting the ! on println

rust
fn main() {
    println("Hello, world!");
}
error[E0423]: expected function, found macro `println`
 --> main.rs:2:5
  |
2 |     println("Hello, world!");
  |     ^^^^^^^ not a function
  |
help: use `!` to invoke the macro
  |
2 |     println!("Hello, world!");
  |            +
Why the compiler said that

println without ! would be a function call, and no function by that name exists. Printing is a macro in Rust because it checks your format string against the arguments at compile time — a function cannot do that.

The fix

Write println!. The compiler even says so in its help line.

rust
fn main() {
    println!("Hello, world!");
}
04

Cargo: new, run, build, check

rustc main.rs is fine for one file. Real projects use cargo, which creates the folder layout, compiles only what changed, downloads dependencies and runs tests. You will almost never call rustc by hand once you have a project.

bash
cargo new hello        # creates hello/ with Cargo.toml and src/main.rs
cd hello
cargo run              # compile (debug) and run
cargo build            # compile only: target/debug/hello
cargo build --release  # optimised build: target/release/hello
cargo check            # type-check without producing a binary (fastest)
cargo test             # run the tests
cargo fmt              # format the code
cargo clippy           # lint: hundreds of extra checks
tomlCargo.toml
[package]
name = "hello"
version = "0.1.0"
edition = "2021"

[dependencies]
# crates from crates.io go here, e.g. serde = "1"

Cargo.toml is the project manifest. edition picks the language edition; [dependencies] lists libraries, which Rust calls crates.

PathWhat it is
Cargo.tomlName, version, edition and dependencies
Cargo.lockExact versions of every dependency, written by cargo — commit it for applications
src/main.rsEntry point of a binary (a program you run)
src/lib.rsEntry point of a library crate (cargo new --lib)
target/Build output — never commit it

cargo build (debug)

  • Compiles fast
  • Keeps debug info for the debugger
  • Integer overflow panics instead of wrapping
  • Use while developing

cargo build --release

  • Compiles slower, runs much faster
  • Full optimisation
  • Integer overflow wraps silently (Module 01)
  • Use for benchmarks and anything you ship
Never benchmark a debug build
A debug build can be 10 to 50 times slower than a release build. "Rust is slow" posts on forums are almost always someone timing cargo run without --release.
05

How a Rust program is structured

A slightly bigger program shows the pieces you will see in every file: use lines that bring names into scope, functions declared with fn, variables declared with let, and statements ending in ;. Rust does not care about the order of functions in a file — main can call a function defined below it.

rustmain.rs
// A line comment. The compiler ignores it.
/* A block comment
   can span lines. */

/// A doc comment: documents the item below it (cargo doc turns these into HTML).
fn area(width: u32, height: u32) -> u32 {
    width * height // the last expression, with no semicolon, is the return value
}

fn main() {
    let w = 8;
    let h = 5;
    let a = area(w, h);
    println!("A {w} by {h} room has an area of {a} square metres.");
    println!("Twice that is {}.", a * 2);
}
Outputcompiled & run with real Rust
A 8 by 5 room has an area of 40 square metres.
Twice that is 80.
Your turn

Add a function perimeter(width: u32, height: u32) -> u32 and print the room's perimeter too.

  • fn name(param: Type) -> ReturnType — parameter types are always written; Rust never guesses them.
  • let makes a variable. It is immutable unless you write let mut (Module 01).
  • {w} inside a format string prints the variable w; {} takes the next argument.
  • A block's last line without a semicolon is its value — that is how area returns. Module 02 explains expressions vs statements.
  • Names use snake_case for functions and variables, CamelCase for types, SCREAMING_CASE for constants.
Error you will hit

Passing the wrong type

rust
fn area(width: u32, height: u32) -> u32 {
    width * height
}

fn main() {
    let a = area(8, "5");
    println!("{a}");
}
error[E0308]: mismatched types
 --> main.rs:6:21
  |
6 |     let a = area(8, "5");
  |             ----    ^^^ expected `u32`, found `&str`
  |             |
  |             arguments to this function are incorrect
  |
note: function defined here
 --> main.rs:1:4
  |
1 | fn area(width: u32, height: u32) -> u32 {
  |    ^^^^             -----------
Why the compiler said that

Rust is statically typed and does no automatic conversion: a string slice &str is never silently turned into a number. The compiler checks every call against the function signature.

The fix

Pass a number. If the value really arrives as text (from input, a file), parse it first with "5".parse::<u32>() — Module 01 shows how.

rust
fn area(width: u32, height: u32) -> u32 {
    width * height
}

fn main() {
    let a = area(8, 5);
    println!("{a}");
}
rustc
The Rust compiler. Turns .rs source into a native executable.
cargo
Rust's build tool and package manager: cargo new, run, build, test, check.
rustup
The installer and version manager for the Rust toolchain.
Crate
A Rust package or compilation unit — a binary (has main) or a library. Published crates live on crates.io.
Macro
Code that writes code at compile time. Called with a !: println!, vec!, panic!.
Edition
A named set of language rules (2015, 2018, 2021, 2024) chosen per crate in Cargo.toml. Crates of different editions work together.
Borrow checker
The part of the compiler that enforces ownership and borrowing rules, so memory bugs become compile errors.
Quick check

Why does Rust not need a garbage collector?

06

How this handbook works

Seventeen modules, each its own page, from let to a job. Rust cannot run inside a browser tab the way Python or JavaScript can, so this handbook takes a different route: every example is a complete program shown with the exact output it prints. Before a page is published, every one of those programs is compiled with the real rustc (2021 edition, stable, standard library only) and run, and the page is rejected if the output does not match character for character.

  • Examples — copy one into src/main.rs of a cargo new project (or a single main.rs) and run it. You will see exactly what the page shows. Then do the "Your turn" task.
  • Error cards — real compiler messages (error[E0382]: borrow of moved value and friends), copied from actually compiling the broken code, with why it happens and the fix. Module 11 collects the fifteen every beginner hits.
  • Traces — step-by-step walk-throughs of what the program did, including where values move and where they are dropped.
  • Interview questions appear next to the topic they test, and Module 15 has sixty more, tiered junior, mid and senior.
  • The floating board keeps the key terms and error cards of the page you are on one click away.
  • At the end: a 25-question certification exam, then the ATS resume checker with a real job posting.
  1. 1
    Modules 01–02

    Variables, types, control flow and functions — the parts that look like other languages.

  2. 2
    Module 03

    Ownership and borrowing. Slow down here; everything after depends on it.

  3. 3
    Modules 04–07

    Structs, enums and match; collections; error handling with Result and ?; traits and generics.

  4. 4
    Modules 08–10

    Lifetimes, closures and iterators, smart pointers and fearless concurrency.

  5. 5
    Modules 11–16

    Debugging, Rust with real tools, data structures, problem solving, interview questions and getting hired.

07

Using AI to learn Rust (without letting it learn for you)

An AI assistant can produce Rust that compiles. But the skill employers pay for is understanding why the borrow checker rejected something and how to restructure the code so it is happy. If the AI fixes every error for you, you never build that model — and then you are stuck the first time it suggests .clone() everywhere or wraps everything in Rc<RefCell<...>>.

Do this

  • Read the compiler error yourself first, all of it, including the help: lines
  • Paste an error and ask "which rule did I break and why does that rule exist?"
  • Write it yourself, then ask for a review of ownership choices
  • Ask for a smaller example that triggers the same error

Not this

  • Paste the "Your turn" task and copy the answer
  • Accept a .clone() or unwrap() you cannot justify
  • Reach for unsafe because an AI said it would compile
  • Use it in a live interview

Ready? Module 01 starts with variables, mutability, the number types and printing.

Every lesson in the handbook

17 modules · 140 lessons · each one ticks itself when you reach the end.

00Getting Started0 / 7
01Fundamentals0 / 8
02Flow Control & Functions0 / 6
03Ownership & Borrowing0 / 8
04Structs, Enums & Matching0 / 8
05Collections & Strings0 / 7
06Error Handling0 / 7
07Traits & Generics0 / 7
08Lifetimes0 / 7
09Closures & Iterators0 / 7
10Smart Pointers & Concurrency0 / 9
11Errors & Debugging0 / 8
12Rust + Tools0 / 7
13Data Structures & Algorithms0 / 11
14Problem Solving0 / 12
15Interview Questions0 / 15
16Job Ready0 / 6

Frequently asked questions

Is this Rust handbook free?
Yes — every module, every example and the certification exam are free, with no signup and no paywall. The exam asks you to sign in with Google so the certificate can carry your name.
Do I need to know another programming language first?
No. Module 01 starts from variables and types and assumes nothing. If you already know another language you will move faster, and the handbook calls out where Rust differs: immutable variables by default, no null, no exceptions, and ownership and borrowing, which Module 03 explains from the ground up.
Do I need to install anything?
Yes — the Rust toolchain, and Module 00 shows how to install it with rustup and run your first program. The examples on this page do not run in the browser; instead, each example program was compiled with rustc and run before publishing, using only the standard library, and the output shown is exactly what it printed, so you can paste it into src/main.rs and get the same result. The labs in Module 12 need crates such as tokio, axum and sqlx, so they are shown as clearly marked snippets.
Which version of Rust does this handbook use?
Current stable Rust with the 2021 edition, installed and kept up to date with rustup update. The compiler errors on the error cards are real messages copied from compiling the broken code, so what you see in your terminal matches what the page shows.
Is there a certificate?
Yes. Pass the 25-question exam (35 minutes) with 70% or more and generate a SolutionGigs Rust certificate with your name, score, date and a certificate ID — download it, print it or add it to LinkedIn.
Is Rust hard to learn?
The syntax is no harder than any C-family language. The genuinely new idea is ownership and borrowing, which usually takes a couple of weeks of fighting the compiler before it clicks. After that, most people find Rust easier to get right than C or C++, because the compiler catches the bugs those languages leave for runtime.
Should I learn Rust as my first programming language?
You can, but it is easier as a second language. If you already know Python, JavaScript, Go or Java, you only have to learn the new ideas; if Rust is your first, you learn programming and ownership at the same time. This handbook explains every term as it appears, so either route works.
What is the difference between rustc and cargo?
rustc is the compiler: it turns one crate's source into a binary. cargo is the build tool that calls rustc for you, downloads dependencies, runs tests and manages the project. Use cargo for anything bigger than a single file.

Finish the Rust handbook, then get hired

Sit the exam for your certificate, run your resume through the ATS checker, and see the jobs that ask for exactly this.

Check my resume
Found this course useful? Share it.
ShareXLinkedIn

Comments

0

Join the conversation. Sign in to leave a comment — we'd love to hear your thoughts.