Short reading lessons on the core of the Rust language, from your first program to traits, lifetimes and concurrency. Each lesson ends with the challenges that practise it, so read one, then solve its challenges.
Install Rust, create a project with Cargo, and print to the terminal with println! and its format strings.
Declare variables with let, opt into change with mut, reuse names with shadowing, and define constants with const.
Integers, floats, booleans and characters, how arithmetic works on them, what happens on overflow, and converting between them with as.
Group values with tuples and fixed-size arrays, pull them apart with destructuring and indexing, and meet (), the type of no value.
Define functions with typed parameters and return values, and learn the difference between statements and expressions that makes Rust's implicit returns work.
Make decisions with if and else, use if as an expression, and repeat work with loop, while and for over ranges.
How Rust manages memory without a garbage collector: owners, moves, clones, shared and mutable references, the borrow rules, and the difference between String and &str.
Borrow part of an array, vector or string with slices: range syntax, &[T] and &mut [T] parameters, string slices and char boundaries, and the everyday slice methods.
Group related data into your own types with structs: named, tuple and unit structs, printing them with #[derive(Debug)], and giving them behaviour with impl blocks, methods and associated functions.
Model values that can be one of several kinds with enums, carry data in their variants, and take them apart with match, if let, let else, guards and bindings. Plus comparing enums with #[derive(PartialEq)].
Store a growing list of values in a Vec and look values up by key in a HashMap: creating, reading, updating and iterating, the entry API, and the borrow rules that apply to both.
Represent a value that might be missing with Option and an operation that might fail with Result: handling both with match and their helper methods, custom error types, and converting between the two.
Pass errors up to the caller with the ? operator, stop the program with panic!, unwrap and expect, and how to choose between them.
Describe shared behaviour with traits: defining and implementing them, default methods, implementing standard traits like Display, deriving traits, and the Default trait.
Write one function, struct or enum for many types with generics, limit them with trait bounds and where clauses, convert with From, Into and AsRef, and hide types behind impl Trait.
Mix different types behind one trait with dyn Trait: references and Box<dyn Trait>, collections and fields of trait objects, static vs dynamic dispatch, and which traits can be made into objects.
Associated types, supertraits, operator overloading with std::ops, default type parameters, and fully qualified syntax for calling the right method.
How Rust makes sure references never outlive their data: lifetime annotations in functions, the elision rules, structs that hold shared and mutable references, and 'static.
Anonymous functions that capture their environment, the Fn, FnMut and FnOnce traits, move closures, and processing sequences with lazy iterator adapters and consumers.
Box for heap allocation and recursive types, Deref and deref coercion, cleanup with Drop, shared ownership with Rc, and interior mutability with Cell and RefCell.
Running code on several threads: spawning and joining threads, move closures, scoped threads, message passing with channels, shared state with Arc and Mutex, and the Send and Sync traits.
Code that writes code: declarative macros with macro_rules!, fragment specifiers, several rules, repetition and recursion, generating items, and what procedural macros are.