How to use this Rust learning guide

These Rust programming notes come from reading real Rust code and asking “why?” at every line. Each note takes one idea, explains it in plain English first, and then backs it up with code you can run.

  • Read in order. The notes go from the foundation (ownership) up to how files fit together (modules). Each one links back to what it builds on.
  • Use the sidebar. Click a note to open it, or a subsection to jump straight to that part. Next → at the bottom of every page continues the path.
  • Run the code. Every snippet comes from one small demo project (below). Breaking the code on purpose and reading the compiler error is the fastest way to learn Rust.
  • Coming from Python? Most sections compare the Rust idea with its closest Python equivalent.

The demo project used in these Rust notes

Every note uses one small Cargo project, shapes_demo, so the examples connect. Each note shows the files it needs. This is the whole project:

shapes_demo/
├── Cargo.toml
├── examples/               <- small experiments: cargo run --example <name>
└── src/
    ├── lib.rs              <- library crate root (Note 10)
    ├── main.rs             <- binary that uses the library (Note 10)
    ├── point.rs            <- Point + Display (Note 10)
    └── math/
        ├── mod.rs          <- declares the modules, DEFAULT_TOLERANCE, approx_eq
        ├── matrix.rs       <- the main file: DimensionMismatch, Vector, Vector2,
        │                      Matrix2, rotate_vector and the tests (Notes 01-11)
        ├── complex.rs      <- Complex, + via the Add trait (Notes 05, 06)
        ├── magnitude.rs    <- the Magnitude trait (Note 05)
        └── trigonometry.rs <- sin_cos (Notes 07, 10)

Create it with cargo new --lib shapes_demo, add the files as each note shows them, and run cargo run. Put small experiments in examples/<name>.rs and run them with cargo run --example <name>. Run cargo test for the unit tests and doc tests (Note 11).

I compiled every snippet and every quoted compiler error in this guide with Rust 1.99, so you should see the same messages.

Rust concept index: where each idea is explained

Every concept is explained in one place. Other notes link back to it instead of repeating it. Use this table to jump straight to a concept:

Concept Note
Ownership, move, drop 01
Borrowing &T / &mut T, self / &self / &mut self 01
struct, impl, Display, write! 02
Implicit return (last line without ;) 02
Private fields and encapsulation 03
Vec<T> and generic parameters 03
Associated functions vs methods, Self, field init shorthand 03
Naming conventions (new, from_, into_, as_, to_) 03
Slices &[T], to_vec 04
Deref coercion &Vec<T> → &[T] 04
Lifetimes and lifetime elision 04
Traits, generics, impl Trait, dyn Trait 05
#[derive] and attributes 06
Arrays [T; N], type aliases 07
const, associated constants, const fn 07
Destructuring and tuples 07
Free functions, number literals 07
Enums, Result, Ok, Err, match 08
if as an expression 08
The ? operator 08
std::error::Error, Box<dyn Error> 08
unwrap, expect, panics vs Result 08
Iterators: iter, zip, map, collect, sum 09
Closures 09
Type inference and the turbofish ::<> 09
for loops and ranges 0..2, 0..=2 09
Modules, use, crate::, pub 10
Comments //, ///, //! and cargo doc 11
Doc tests 11
#[cfg(test)], mod tests, use super::* 11
#[test], assert_eq!, #[should_panic] 11

The notes in this Rust guide

Each note builds on the one before it:

  1. Note 01 Rust Ownership and Borrowing, Explained from Scratch Rust ownership and borrowing explained from scratch: stack vs heap, the three ownership rules, move, Copy, Clone, &T vs &mut T, with compiler-checked examples.
  2. Note 02 Rust Structs, impl and the Display Trait, Line by Line Rust structs, impl blocks and the Display trait explained line by line: &self, fmt::Formatter, fmt::Result, the write! macro and the missing semicolon.
  3. Note 03 Rust Methods, Constructors and Encapsulation: Building the Vector Type Rust methods and constructors explained: associated functions vs methods, Self, field init shorthand, private fields for encapsulation and naming rules.
  4. Note 04 Rust Slices and Lifetimes: &[T], Deref Coercion and Lifetime Elision Rust slices and lifetimes explained: what &[f64] is, slicing with ranges, to_vec, owning vs borrowing constructors, deref coercion and lifetime elision.
  5. Note 05 Rust Traits Explained: Shared Behaviour, Generics and dyn Trait Rust traits explained for beginners: define and implement a trait, default methods, trait bounds and generics, impl Trait, dyn Trait and the orphan rule.
  6. Note 06 Rust #[derive] Explained: Debug, Clone, Copy, PartialEq and Eq Rust #[derive] explained in plain English: what attributes are, what Debug, Clone, Copy, PartialEq and Eq give you, and why f64 and Vec limit derives.
  7. Note 07 Rust Arrays, Tuples, Constants and Destructuring: The Matrix2 Type Rust arrays, tuples and constants explained with a 2x2 matrix: [T; N] vs Vec, type aliases, const fn, destructuring, free functions and number literals.
  8. Note 08 Rust Error Handling: Result, Enums, the ? Operator and Panics Rust error handling for beginners: enums, Result, Ok and Err, match, the ? operator, std::error::Error, Box, unwrap vs expect and when to panic.
  9. Note 09 Rust Iterators and Closures: zip, map, collect, sum and the Turbofish Rust iterators and closures explained step by step: iter vs iter_mut vs into_iter, zip, map, collect, type inference, laziness, sum and the turbofish.
  10. Note 10 Rust Modules and use: Importing with crate:: Paths Rust modules and the use keyword explained: how crate:: paths are read, why mod declarations build the module tree, std::fmt, and when pub is required.
  11. Note 11 Rust Comments, Doc Tests and Unit Tests: //!, ///, #[test] and cargo test Rust documentation and testing explained: //, /// and //! comments, cargo doc, doc tests, #[cfg(test)] modules, #[test], assert_eq! and #[should_panic].