3.1 KiB
Smart Pointers
A pointer is a concept for a variable that contains an address in memory.
This address refers or "points at", some other data.
In Rust the most common kind of pointer is a reference.
References are indicated by the &
symbol and borrow the value they point to.
They don't have any additional or special capabilities other than referring to data and have no overhead.
Smart pointers are data structures that act like a pointer but also have addtional metadata and capabilities.
This idea of smart pointers is not unique to Rust.
Smart pointers come from C++ and exist in other languages as well.
Rust has a variety of smart pointers defined in the std library that provide functionality beyond that provided by references.
To explore the general concept, we will look at a couple of different examples of smart pointers, including a reference counting smart pointer type.
This pointer enables you to allow data to have multiple owners by keeping track of the number of owners and when there are no more owners remaining, clean up the data.
With the concept of ownership and borrowing in Rust it has an additional difference between references and smart pointers.
While references only borrow data, in many cases, smart pointers own the data they point to.
Even though we havent called them smart pinters before we have already interacted with a few smart pointers in previous chapters.
This includes String
and Vec<T>
.
Both of these types count as smart pointers because they own some memory and allow you to manipulate it.
They both contain metadata and extra capabilities or guarantees.
As an example String
stores its capacity as metadata and has the extra ability to enusre its data will always be valid UTF-8.
Smart pointers are usually implemented using structs.
Unlike an ordinary struct, smart pointers implements the Deref
and Drop
traits.
The Deref
trait allows an instance of the smart pointer struct to behave like a reference so you can write your code to with either references or smart pointers. Section Link Here
The Drop
trait allows you to customize the code that is run when an instance of the smart pointer goes out of scope. Section Link Here
We will go over both traits and demonstrate why they are improtant to smart pointers.
Given that the smart pointer pattern is a general design used often in Rust, we won't ocver every existing smart pointer.
Many libraries have thier own smart pointers, and you can even write your own.
The ones we will cover are the most common smart pointers in the std library:
Box<T>
for allocating values on the heapRc<T>
, a reference counting type that enables multiple ownership Section Link HereRef<T>
andRefMut<T>
this is accessed throughRefCell<T>
, a type that enforces the borrowing rules at runtime instead of compile time
In additon we will also cover interior mutability patter where an immutable tpye exposes an API for mutating an interior value.
As well discuss reference cycles; how they can leak memory and how to prevent them.