ruk·si

🦀 Rust
Smart Pointers

Updated at 2024-02-27 20:01

The most common smart pointers are String and Vec<T>.

Smart pointers are data structures that work like pointers under the hood.

Smart pointer implements Deref and Drop traits.

  • the Deref makes it a reference that can act like the referenced value
  • the Drop allows cleaning when it goes out-of-scope
  • together they are "smart", knows to clean itself but feel like the concrete value

You can also force a drop with std::mem::drop.

The simplest smart pointer is Box<T>. It allows indirection and store dynamic data in the heap. Those are its only capabilities.

The most common use-cases for smart pointers:

  • you want to use a type with unknown size in context that requires a known size
    • Rust must know the size of each type at compile-time
  • you have huge amounts of data that will change ownership
    • to guard against expensive copying on ownership transfer
  • you want to own a value but only care about one trait that it implements
    • aka. trait object-based generics

Reference Counters are Smart Pointers

Rc<T> implements reference counting for single-threaded code; you are not sure which part of your code finishes with T the last, call Rc::clone to create a new tracked reference and the value is only cleaned after all references are dropped.

You should use Rc::clone instead of clone to avoid confusion.

Arc<T> is a multithreaded version of reference counting.

The A there stands for "atomic".

Cell<T> allows shared mutability in single-threaded code.

Mutex<T> allows shared mutability in multithreaded code.

RefCell<T> allows manual borrow rules during runtime in single-threaded code.

let counter = Arc::new(Mutex:: new(0)); 
for _ in 0..10 { let counter = Arc::clone(&counter); }

Trait Object are Smart Pointers

To use variables solely according to trait, you must use trait objects.

You define a trait object type by:

  • putting dyn Trait behind a reference like &dyn Trait
  • with a smart pointer like Box<dyn Trait>
  • in certain contexts using more modern impl Trait

Sources