🎓 A1Learner
🔍

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?