
Recently I've been learning and building in Rust to the point where I'm feeling productive with it.
Like many others, I've found the "The Rust Programming Language" book (or "the book" as my rustacean friends like to call it) to be an incredibly helpful resource. But as I've progressed beyond the book I've found that reading the source code of the standard library and the crates I was using was extremely illuminating, and revealed common motifs in Rust development.
There are a few things I've found that I thought might be especially helpful for those new to Rust, which I've collected here.
Rc<RefCell<T>> (or Arc<RwLock<T>> or Arc<Mutex<T>>)
This one is in the book, but it's in the last 3/4, and if you're jumping into the language you might be worried that data structures that were easy in other languages might seem impossible in Rust.
Rc<T> and its thread-safe
counterpart Arc<T>
allow you to reference-count
(or in the case of Arc, atomically reference-count)
allocated memory.
.clone() on an Rc<T> will no longer .clone() (and copy) the
wrapped value. Instead, a counter representing how many times the Rc
is owned will be incremented and the same Rc will be effectively owned in
multiple places. As these owned references are dropped the counter decrements,
and when the last reference is finally dropped, Rc will drop the wrapped value
before it is removed itself.
Rc implements Deref
(but not DerefMut), which allows
you to easily access the value it wraps via "Deref coercion".
Meanwhile, RefCell<T>
(or RwLock<T> and
Mutex<T>)
lets you separate the mutability
of the type that they wrap from the struct or reference that holds it. This
is called "interior mutability".
Anywhere a RefCell, RwLock or Mutex is
borrowed as immutable, you can try to mutably borrow the
interior value with .borrow_mut or similar.
RefCell<T> and Rc<T> (and their respective thread-safe counterparts)
can be combined to create a value that can be shared (with Rc) and mutated
in multiple places
(inside of a RefCell, which temporarily provides a borrowed mut value).
Rc<T>can be owned in many places with.clone()- Each clone of
Rcpoints to the same immutable value - You can ask to mutably borrow the value inside the
RefCellanywhere theRefCellis immutably borrowed - A
RefCell<T>wrapped inRccan be borrowed immutably anywhere theRcis owned - You can ask to mutably borrow the value inside the
RefCellanywhere theRcis owned - With this pattern, the interface to ask to borrow a shared value mutably can have many owners
One data structure that might be impossible or needlessly difficult to
create in Rust without reference counting and
interior mutability is a graph. Below is an example that
uses reference counting with Rc<T> to create nodes, one of which is referenced multiple
times from multiple other nodes. RefCell<T> is utilized to borrow a mutable
reference to the node so …




SpiralSynthModular, an old modular softsynth that left an impression on me
A real, physical, Doepfer A-100 modular synthesizer. (


