Smart Pointers Best Practices
How to Use This List
- Default to references/ownership; escalate to smart pointers with justification.
- Review
Arc<Mutex>proliferation in concurrent code.
A - Selection
- Prefer
&T/ ownedTbeforeRc/Arc. Simpler ownership. - Use
Boxfor heap single owner or trait objects. Not default for all heap data. -
Rcsingle-thread only;Arcfor threads. Compiler enforces Send where needed. -
RefCellonly single-thread interior mutability.Mutexacross threads. -
Cowfor maybe-mutate borrowed text. Avoid gratuitousStringparams.
B - Concurrency
- Prefer channels over
Arc<Mutex>when possible. Clearer data flow. - Use atomics for simple counters. Not
Mutex<u64>always. - Do not hold std
Mutexguards across.await. Usetokio::sync. - Handle poisoned mutex explicitly in production. Log and recover policy.
- Document lock ordering if multiple mutexes. Deadlock prevention.
C - Cycles and Memory
- Break
Rccycles withWeakback edges. Trees: parent Weak. - Avoid long-lived
Rccaches without eviction. Memory growth. - Profile
Arc::clonehot paths. Atomic inc cost. - Use
Weak::upgradehandlingNone. Owner may be gone. - Consider arena + indices over
Rc<RefCell>graphs. Performance.
D - API Design
- Expose
&strnotRc<str>unless sharing required. API simplicity. - Hide
RefCellinside type; don't leak guards. Encapsulation. - Implement
Derefnot inheritance for newtypes. Transparent access. - Custom
Dropdocuments safety invariants. Especially FFI. - Test drop order and RAII with flags in unit tests.
FAQs
Arc always for async?
Shared state yes; not every value.Rc in wasm?
Single-thread ok.Pin when?
Self-referential futures.Box error?
App boundary ok.lazy_static?
OnceLock/Rc/Arc static patterns.smallvec with Rc?
Different concerns.miri RefCell?
Catch double borrow.serde Rc?
Serializes inner.upgrade perf?
Cheap atomic on Arc.next?
Strings and text handling.Related
- Smart Pointers Basics
- Ownership Best Practices
- Concurrency Best Practices
- Fighting the Borrow Checker
Stack versions: This page was written for Rust 1.97.0 (edition 2024), Tokio 1.x, Axum 0.8, serde 1.0, sqlx 0.8, clap 4, and Polars 0.46+.