Course Overview
Learn Rust programming with a practical, hands-on approach! This course combines theory with numerous exercises, guiding you through Rust's unique features and robust compiler. Starting with an overview of Rust's powerful tools and ecosystem, you'll master basic and advanced concepts, including ownership, lifetimes, generics, and concurrency. Experience the benefits of Rust's safety and performance, and explore topics like traits, pointers, and error handling. Ideal for developers seeking to enhance their skills with one of the most loved programming languages.
Course Prerequisites
No previous knowledge of Rust is assumed. Familiarity with programming is assumed: if you are not able to write a working implementation of FizzBuzz in under ten minutes in some programming language, then you are probably not ready to attend the course. Familiarity with C++ is not a prerequisite for this course, but is beneficial.
Outline
-
This is a hands-on course: theory is interleaved with numerous practical exercises, and ideas are constantly illustrated and explored up by inspecting the compiler's response to illustrative code samples.
Rust's compiler error messages have advanced the state of the art in terms of helpfulness. The course tries to emphasize how much can be learned about the language by reading the compiler error messages.
-
The course tries to follow a path through the material which introduces only one new concept at a time. However, Rust is a complex language where the concepts form a dense and cyclic dependency graph, so it is not entirely possible to live up to this goal.
-
The tooling that comes with Rust is tightly integrated into the workflow of the Rust programmer, and probably a significant contributing factor to Rust's consistent top spot in the GitHub Survey's ranking of languages most-loved by their users. The course starts with an overview of these tools and the ecosystem that has grown as a consequence of their existence, and will continue to use many of them throughout.
Some ideas are difficult to convey adequately in natural language alone and are best demonstrated with concrete examples in some programming language, and seeing the compile-time and run-time results can be very illuminating; C++ is sometimes the best choice in this context.
Consequently, a small number of the exercises ask the participants to translate small samples of C++ code into Rust, usually to demonstrate how the Rust compiler refuses to accept unsound code. The meaning of this sample code will be explained patiently to anyone not familiar with C++.
-
Some topics which are explicitly NOT covered in this course:
- writing
unsafe
Rust async
- implementation of procedural macros
- details of
String
manipulation
- writing
Detailed Topics
- Why Rust
- Installing the toolchain
- Cargo features
- the manifest
- managing libraries and executables
- unit tests
- integration tests
- examples
- docs
- benchmarks
- Preludes
- std vs core: no operating system, no problem
- Basic language features
- functions
- expression-orientation
- type declaration and inference
- attributes
- modules
- Review, consolidation and integration of concepts
- Previews
- pattern matching
- Option: avoiding the billion-dollar mistake
- ownership semantics triad
- Types and traits
- unit structs
- never
- tuple structs
- associated functions
- traits
- structs
- enums
- Review, consolidation and integration of concepts
- Ownership
- copy and move semantics
- shared refs
- exclusive refs
- ref rules in action
- methods
- non-lexical lifetimes
- reborrows
- borrow splitting
- interior mutability
- Review, consolidation and integration of concepts
- Generics and traits
Display
- generic types
From
andInto
- blanket implementations
- generic functions
- operator overloading
- coherence and the orphan rule
- impl Trait in argument position
- impl Trait in return position
- Pointers
- fat/wide pointers
- stack and heap
- arrays
- dynamically-sized types
- slices
- vectors
- review, consolidation and integration of concepts
Deref
- deref coercion
- smart pointers
- static polymorphism
- dynamic dispatch
- trait objects
- dangling pointers and memory leaks are disallowed
- dynamic return type
- Lifetimes
- syntax
- semantics
- elision
- Closures
- syntax
- type inference
- moves, copies, shared- and exclusive-borrows
- capture
- two distinct binding times
FnOnce
,FnMut
andFn
- under the hood of closures
- types with lifetimes
- Fn-traits recapitulation
- forcing transfer of ownership
- fine-grained control of capture
- returning closures
- Dealing with errors
- panics
- when to panic
- Result and Option
- ergonomics
- functors and monads
- the
?
operator thiserror
: developer-facing error ergonomicsanyhow
: user-facing error ergonomics- review, consolidation and integration of concepts
- Iterators
- for-loops
- consuming, shared and mutable iteration
- digression: stretching but not breaking the boundaries of safe Rust
- laziness
- internal and external iteration
collect
- adapters
- consumers (catamorphisms)
- producers (anamorphisms)
copied
andcloned
- nested loops
- overview of utilities
- fallible iteration
- Fearless concurrency
- data races eliminated at compile time
- aliasing XOR mutability
- Mutex
- interior mutability
- stretching the boundaries
- Rc and Arc
- Send and Sync
- marker traits and auto traits
- data concurrency: Rayon
- channels
- Builder pattern
- Type-driven development
- typestate