Rust Smart Pointers
A smart pointer is a handle with a small brain. It points at a value, owns it, and does extra work.
Box: one owner, value on the heap
The Box is a small pointer you own. The star follows it to the value behind it.
let boxed = Box::new(5);
println!("{}", *boxed);Rc: many owners, one value
Rc::clone adds an owner. It raises the count — the value itself is not copied.
use std::rc::Rc;
let shared = Rc::new(10);
let _copy = Rc::clone(&shared);
println!("owners = {}", Rc::strong_count(&shared));RefCell: borrows checked while running
One owner, but the inside can change. borrow_mut() takes the one allowed write borrow. borrow() reads.
use std::cell::RefCell;
let cell = RefCell::new(vec![1, 2]);
cell.borrow_mut().push(3);
println!("{:?}", cell.borrow());Example
fn main() {
let boxed = Box::new(5);
let shared = std::rc::Rc::new(10);
let copy = std::rc::Rc::clone(&shared);
println!("boxed = {} shared = {} owners = {}", *boxed, *copy, std::rc::Rc::strong_count(&shared));
}Key points
- Smart pointers implement Deref, so they can be used like a reference.
- They also implement Drop.
- Cleanup runs when they go out of scope.
- Pick in two steps: first count the owners (one, or many?), then ask when borrows should be checked (while compiling, or while running?)
- That is the big difference from references, which only borrow.
- Ownership is why a smart pointer can decide when its value is freed.
- Box, Rc and RefCell are the three smart pointers in this section.
In this example, boxed is a Box holding the number 5 on the heap. *boxed follows the pointer to read it. shared is an Rc holding 10. Rc::clone makes copy a second owner of the same 10 — the number itself is not copied. strong_count then reports 2 owners. Two smart pointers, two different jobs: the Box stores, the Rc shares.
Note
Smart pointers own the data they point to.
Try it Yourself
Edit the code, then press Run.
Running is simulated · Rust Playground
Exercise
What makes a pointer "smart" in Rust?