You've already forked comprehensive-rust
mirror of
https://github.com/google/comprehensive-rust.git
synced 2025-07-16 19:14:20 +02:00
Embed course outline in the welcome page
This commit is contained in:
@ -24,3 +24,88 @@ decisions within the context and constraints of your own projects.
|
||||
## Schedule
|
||||
|
||||
{{%session outline}}
|
||||
|
||||
<details name="Course outline">
|
||||
|
||||
<!-- TODO: Remove this `details` section once the course material is finalized -->
|
||||
|
||||
The course will cover the topics listed below. Each topic may be covered in one
|
||||
or more slides, depending on its complexity and relevance.
|
||||
|
||||
### Foundations of API design
|
||||
|
||||
- Golden rule: prioritize clarity and readability at the callsite. People will
|
||||
spend much more time reading the call sites than declarations of the functions
|
||||
being called.
|
||||
- Make your API predictable
|
||||
- Follow naming conventions (case conventions, prefer vocabulary precedented
|
||||
in the standard library - e.g., methods should be called "push" not
|
||||
"push_back", "is_empty" not "empty" etc.)
|
||||
- Know the vocabulary types and traits in the standard library, and use them
|
||||
in your APIs. If something feels like a basic type/algorithm, check in the
|
||||
standard library first.
|
||||
- Use well-established API design patterns that we will discuss later in this
|
||||
class (e.g., newtype, owned/view type pairs, error handling)
|
||||
- Write meaningful and effective doc comments (e.g., don't merely repeat the
|
||||
method name with spaces instead of underscores, don't repeat the same
|
||||
information just to fill out every markdown tag, provide usage examples)
|
||||
|
||||
### Leveraging the type system
|
||||
|
||||
- Short recap on enums, structs and type aliases
|
||||
- Newtype pattern and encapsulation: parse, don't validate
|
||||
- Extension traits: avoid the newtype pattern when you want to provide
|
||||
additional behaviour
|
||||
- RAII, scope guards and drop bombs: using `Drop` to clean up resources, trigger
|
||||
actions or enforce invariants
|
||||
- "Token" types: force users to prove they've performed a specific action
|
||||
- The typestate pattern: enforce correct state transitions at compile-time
|
||||
- Using the borrow checker to enforce invariants that have nothing to do with
|
||||
memory ownership
|
||||
- OwnedFd/BorrowedFd in the standard library
|
||||
- [Branded types](https://plv.mpi-sws.org/rustbelt/ghostcell/paper.pdf)
|
||||
|
||||
### Don't fight the borrow checker
|
||||
|
||||
- "Owned" types and "view" types: `&str` and `String`, `Path` and `PathBuf`,
|
||||
etc.
|
||||
- Don't hide ownership requirements: avoid hidden `.clone()`, learn to love
|
||||
`Cow`
|
||||
- Split types along ownership boundaries
|
||||
- Structure your ownership hierarchy like a tree
|
||||
- Strategies to manage circular dependencies: reference counting, using indexes
|
||||
instead of references
|
||||
- Interior mutability (Cell, RefCell)
|
||||
- Working with lifetime parameters on user-defined data types
|
||||
|
||||
### Polymorphism in Rust
|
||||
|
||||
- A quick refresher on traits and generic functions
|
||||
- Rust has no inheritance: what are the implications?
|
||||
- Using enums for polymorphism
|
||||
- Using traits for polymorphism
|
||||
- Using composition
|
||||
- How do I pick the most appropriate pattern?
|
||||
- Working with generics
|
||||
- Generic type parameter in a function or trait object as an argument?
|
||||
- Trait bounds don't have to refer to the generic parameter
|
||||
- Type parameters in traits: should it be a generic parameter or an associated
|
||||
type?
|
||||
- Macros: a valuable tool to DRY up code when traits are not enough (or too
|
||||
complex)
|
||||
|
||||
### Error Handling
|
||||
|
||||
- What is the purpose of errors? Recovery vs. reporting.
|
||||
- Result vs. Option
|
||||
- Designing good errors:
|
||||
- Determine the error scope.
|
||||
- Capture additional context as the error flows upwards, crossing scope
|
||||
boundaries.
|
||||
- Leverage the `Error` trait to keep track of the full error chain.
|
||||
- Leverage `thiserror` to reduce boilerplate when defining error types.
|
||||
- `anyhow`
|
||||
- Distinguish fatal errors from recoverable errors using
|
||||
`Result<Result<T, RecoverableError>, FatalError>`.
|
||||
|
||||
</details>
|
||||
|
Reference in New Issue
Block a user