// These are notes for myself, and can be misleading since they may not represent the entire picture, and because I’m still learning Rust.
C pointers vs Rust references:
| C | Rust | Can Change Value? | Can Change Pointer? (To something else) |
|---|---|---|---|
const int *const ptr |
let ptr: &i32 |
❌ No | ❌ No |
const int *ptr |
let mut ptr: &i32 |
❌ No | 🟢 Yes |
int *const ptr |
let ptr: &mut i32 |
🟢 Yes | ❌ No |
int *ptr |
let mut ptr: &mut i32 |
🟢 Yes | 🟢 Yes |
These govern whether the pointer reference allows modifications to the referenced value, and whether the pointer itself can be modified to point to something else.
A key addition in Rust is compile-time book-keeping of references:
- only one mutable reference to a value at a time
- can’t have a mutable and immutable reference at the same time
- can have multiple immutable references at the same time
C will allow all of these, and is mutable by default whereas Rust is immutable by default.
But this only looks at the reference from one side of the arrow - the pointer’s perspective, i.e. whether the user of the pointer is allowed to change the underlying value.
The other side of the arrow is whether the underlying value (that we point to) can change due to external factors. For e.g. a separate pointer being used to modify the value of a const pointer. C allows that, while Rust doesn’t. In C, const int *ptr is a pointer-side guarantee that we can’t use this pointer to change the referenced value. But it doesn’t guarantee that the value won’t change due to external factors (like a different pointer being used to modify it). Rust’s immutable reference guarantees that the actual value won’t change while that reference is valid.
That’s why, an immutable reference feels more like a ‘read lock’, and a mutable reference feels like a ‘read-write lock’.