You've already forked comprehensive-rust
mirror of
https://github.com/google/comprehensive-rust.git
synced 2025-07-17 03:22:22 +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
|
## Schedule
|
||||||
|
|
||||||
{{%session outline}}
|
{{%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