References vs Smart Pointers
A pointer is a general concept for a variable that contains an address in memory; this address refers to or points at some other data. The most common kind of pointer in Rust is a reference, which is indicated by the
& symbol and borrows the value it points to (Read Chapter 4 of the Rust Programming Book for more). This reference does not have special capabilities other than referencing data.
Smart pointers on the other hand are data structures that not only act as pointers but also have additional meta-data and capabilities. The different Smart Pointers defined by Rust's standard library provide functionality beyond that provided by references.
An additional difference between references and smart pointers is that references are pointers that only borrow data; in contrast to smart pointers which, in many cases, own the data they point to.
Some Rust types such as
Vec<T> can count as smart pointers because they own some memory and allow you to manipulate it. They also have metadata (i.e capacity) and extra capabilities or guarantees (i.e
String ensures its data is always valid UTF-8).
Smart pointers are usually implemented using structs. The characteristic that distinguishes a smart pointer from any other struct is that smart pointers implement the
Drop traits. The
Deref trait allows an instance of the smart pointer to behave like a reference so you can write code that works with either references or smart pointers. The
Drop trait on the other hand allows you to customize the code that is run when an instance of the smart pointer goes out of scope. We will discuss more on theses traits later on.
Here are the most common smart pointers in Rust's standard library
Box<T>for allocating values to the heap
Rc<T>, a reference counting type that enables multiple ownership
RefMut<T>, accessed through
RefCell<T>a type that enforces the borrowing rules at runtime instead of compile time to allow for interior mutability.
RefCellcan also be used together as
Rc<RefCell<T>>to achieve multiple ownership and interior mutability in single threaded scenarios.