Everything about Rust that I am learning!
Index
Memory Model
- Lifetimes - time associated to a reference to make sure it is still valid when we need it
- Rust compiler validates a graph of flows between accesses - interpretation of the borrow checker
- The borrow rule (many &T XOR one &mut T) exists to guarantee no aliased mutation β enabling optimization and data-race-freedom - the why behind the rule
- Self-referential structs are impossible in Rust because a move relocates the struct but not its interior pointer β use indices or Pin - moves break interior pointers
- &T Is a Shared Reference, Copy but Not Mutable
- If your code must own data, make the caller provide it. Use Cow when ownership is decided at runtime - good practice
- A Lifetime Names the Region of Code a Reference Must Be Valid For, Not Necessarily the Full Scope - lifetime definition
- βstatic Means Valid Until Program Shutdown β Static Variables Have It, But Not All βstatic References Point to Static Memory
- Rust compiler validates a graph of flows between accesses - interpretation of the borrow checker
- Reference Types and Interior Mutability - Explains the change of mentality between
&T and&mut Tfrom immutable and mutable to the correct ones: shared and exclusive reference. - Recursion - Why recursion is not fully safe in Rust
- Smart Pointers
Type System
- Principle of Least Astonishment
- Make invalid states inexpressible by carving the value-set to match the domain - types are value-sets; structs multiply, enums add
- Generics keep the concrete type, trait objects erase it β that lever generates every tradeoff - static dispatch vs. type erasure
- Object safety is whether a vtable can be built; where Self Sized carves offending methods out of the dyn interface - the gatekeeper for
&dyn - Rust has no runtime reflection β type_name and TypeId are compile-time generics that report the static type - no runtime type info
- std::any::Any is opt-in type-preservation via a TypeId in the vtable β a keyhole that recovers only the original concrete type, not reflection - opt-in downcasting, not reflection
- Object safety is whether a vtable can be built; where Self Sized carves offending methods out of the dyn interface - the gatekeeper for
- The Newtype pattern wraps a single type in a single-field tuple struct -
NewType(type) - non_exhaustive attribute prevents implicit construction and exhaustive matching outside the crate
- Closures
- Implementation from traits can be removed with negative impls
Functional Programming
Concurrency
Best Practices
- Use thiserror for structured error callers can match on, anyhow when error type doesnβt matter
- Consolidate integration tests into one crate and avoid doc tests
- `tracing` models execution as spans and events, richer than flat logging because it captures context
- Principle of Least Astonishment
- Rust code organization
- The Newtype pattern wraps a single type in a single-field tuple struct -
NewType(type) - non_exhaustive attribute prevents implicit construction and exhaustive matching outside the crate
- Cargo links multiple versions of a crate as distinct types, so a version leaking into a public API breaks callers β re-export the dependency - public dependencies & re-exporting