Free course · 12 lessons · Beginner
Rust Fundamentals: Ownership, Errors and Fearless Concurrency
Learn Rust from your first program to safe parallel code: Cargo, types and control flow, ownership and borrowing, structs and enums, pattern matching, error handling with Result and ?, collections and iterators, traits and generics, lifetimes and threads. Every example is compiled with the Rust compiler and shown with its real output, and the course ends with a command-line capstone.
1. Rust Basics and Ownership
Your first programs, Rust's types and control flow, then the ideas that make Rust different: ownership, borrowing and slices. Everything else in Rust builds on these.
- Hello, Rust: Cargo, Variables and Mutability — Create a project with Cargo, print with println!, and learn Rust's variables: immutable by default, mut when you need change, shadowing to transform a value, and constants.
- Types, Functions and Control Flow — Rust's number, boolean, char, tuple and array types, functions with typed parameters, expressions that return values, and if, loop, while, for and ranges.
- Ownership: Rust's Superpower — Every value has one owner; when the owner goes out of scope the value is freed. Assigning or passing a String moves it, Copy types are duplicated, and clone makes an explicit deep copy. This is how Rust is memory-safe without a garbage collector.
- Borrowing, References and Slices — Lend a value with & instead of moving it: any number of shared borrows, or exactly one mutable borrow at a time. Slices (&str, &[T]) borrow part of a collection. These rules prevent data races at compile time.
- Structs and Methods — Group related data in structs, add behaviour with impl blocks (methods with &self, &mut self or self, and associated functions like new), and derive Debug, Clone and PartialEq.
- Enums, Option and Pattern Matching — Enums model 'one of several possibilities', each variant optionally carrying data. Option replaces null, match must handle every case, and if let handles just one.
2. Errors, Collections, Traits and Concurrency
What you need for real programs: Result and the ? operator, Vec and HashMap with iterators and closures, traits and generics, lifetimes, and safe concurrency. Finish with a capstone CLI.
- Error Handling with Result and ? — Recoverable errors are values of type Result<T, E>. Handle them with match, propagate them with ?, define your own error enum, and keep panics for real bugs.
- Vec, HashMap, Iterators and Closures — Store data in Vec and HashMap, and process it with iterator chains (map, filter, fold, collect) and closures. Iterators are lazy and compile down to loops as fast as hand-written ones.
- Traits and Generics — Traits define shared behaviour (like interfaces); generics write code once for many types; trait bounds say what a generic type must be able to do. Implement Display, use impl Trait and dyn Trait.
- Lifetimes Without the Fear — Lifetimes are how the compiler checks that references never outlive the data they point to. Most are inferred; you write them only when a function returns a reference that comes from one of several inputs, or a struct holds a reference.
- Fearless Concurrency: Threads, Channels and Arc<Mutex> — Run work in parallel with threads, pass messages through channels, and share state safely with Arc and Mutex. The type system rejects data races at compile time.
- Capstone: A Word Statistics Tool — Build a small command-line tool that reads text, reports word counts, the most common words and average word length, with proper error handling and tests. Then review it against the rubric.