Rust mutation can be somewhat confusing if you’re a beginner. It’s similar to the C++ way of doing things in where to put the asterisk (*) and ampersand (&) signs in variable declarations. Moving the asterisk and ampersand signs makes the declaration sometimes more mutable, and sometimes less, and the mental gymnastics of tracking who owns what can make your head spin.
The concept at its core is simple, though: Rust has two questions for every variable, “can the pointer be changed?” and “can what it points to be changed?” The four combinations of yes and no produce exactly four cases, and once you see them side by side, the pattern clicks.
Here is a simple diagram on Rust mutation that I found on StackOverflow (SO). I can’t find the exact link to reference as this one is stored in my notes.
a: &T == const T* const a; // can't mutate either
mut a: &T == const T* a; // can't mutate what is pointed to
a: &mut T == T* const a; // can't mutate pointer
mut a: &mut T == T* a; // can mutate both
🧠 Final Thoughts
Read the table once, then read it again with the C++ translation in mind and it stops being a wall of symbols. The mut keyword controls the binding, the variable itself, while &mut T controls the pointee, the data behind it. Mix the two and you get the four cases above.
Bookmark this diagram for the next time the borrow checker argues with you. Half of those arguments are just one of these four combinations in disguise, and now you have the map. Thanks for reading.
