Rust exercises following the book Design Patterns and Best Practices in Rust - Evan Williams
Learning by doing a few bad examples and a few good examples.
Bad Examples with Anti-Patterns in Rust using OOP
Use Box dynamic dispatch everywhere, end up writing a lot of code to force OOP class and interface polymorphism:
Bad Calculator - Source Code:
Leverage enums to perform the same functions but more concisely:
Not So Bad Calculator - Source Code:
Use OO constructors and store more data inside enums to make it more generic that resulted in silent errors:
Slightly Worse Calculator - Source Code:
Overuse enums and sub-enums to scale the code to more use cases end up with code that is very difficult to work with:
The Worst Calculator - Source Code:
Examples for ownership and lifetime management
The advantages the better example offers that the bad examples don’t:
- Clear ownership semantics: Each component should own its data directly, with no unnecessary indirection
- Explicit state management: The struct keeps related data together
- Better error handling: Use Result types to handle errors explicitly
- Thread-safety when needed: Instead of sprinkling Rc and RefCell throughout the code, we provide a separate thread-safe wrapper when concurrent access is required.
- Simpler mental model: We can reason about data flow more easily because ownership and mutation are explicit
- Better performance: We avoid the overhead of reference counting and runtime borrowing checks in the common case
Source Code: