19.9 Summary
Rust’s standard library provides a versatile set of smart pointers that extend its core ownership and borrowing system to handle more complex memory management scenarios safely and efficiently:
Box<T>
: Simple heap allocation with exclusive ownership. Essential for recursive types, trait objects, and controlling data placement.Rc<T>
: Single-threaded reference counting for shared ownership of immutable data. Clones are cheap, increments count. Not thread-safe.Arc<T>
: Thread-safe (atomic) reference counting for shared ownership of immutable data across threads. UseArc::clone
to share.- Interior Mutability (
Cell<T>
,RefCell<T>
,OnceCell<T>
): Allow mutating data through shared references within a single thread.Cell
is forCopy
types (no runtime checks).RefCell
uses runtime borrow checks (panics on violation).OnceCell
handles write-once initialization. Often combined withRc<T>
(e.g.,Rc<RefCell<T>>
). - Thread-Safe Mutability (
Mutex<T>
,RwLock<T>
): Used withArc<T>
(e.g.,Arc<Mutex<T>>
) to allow safe mutation of shared data across multiple threads by ensuring exclusive (Mutex) or shared-read/exclusive-write (RwLock) access. Weak<T>
: Non-owning pointer derived fromRc<T>
orArc<T>
. Does not keep data alive. Used to observe data or, critically, to break reference cycles and prevent memory leaks. Access requiresupgrade()
.
These tools enable developers to implement complex data structures, manage shared state, and build concurrent applications without sacrificing Rust’s core promise of memory safety. They replace the need for manual memory management found in C and mitigate issues sometimes encountered with C++ smart pointers (like dangling raw pointers or undetected cycles) by integrating deeply with the borrow checker and employing runtime checks or atomic operations where necessary. Choosing the right smart pointer for the specific ownership and concurrency requirements is key to writing idiomatic and robust Rust code.