In this lesson, you will learn how Rust automatically "follows" references so you don’t have to manually type the dereference operator (*) every time you access a value.
The "Deref" Shortcut
Usually, if you have a reference like &T, you might expect to manually dereference it using * to get to the underlying T. However, Rust performs implicit dereferencing (often called deref coercion) when calling methods or accessing fields. This is why you can call a method on a reference as if it were the actual value.
Consider this example:
struct Counter {
value: i32,
}
impl Counter {
fn increment(&mut self) {
self.value += 1;
}
}
fn main() {
let mut my_counter = Counter { value: 0 };
let ref_to_counter = &mut my_counter;
// Rust automatically dereferences 'ref_to_counter' here!
ref_to_counter.increment();
}
How It Works
When you write ref_to_counter.increment(), Rust looks at the type of ref_to_counter, which is &mut Counter. It notices that increment expects &mut Counter (via self).
If the types didn't match perfectly—for example, if you had a reference to a reference (&&Counter)—Rust would automatically keep dereferencing the pointer until it reaches the type that matches the method definition. It essentially keeps saying, "Are you the thing I need? No? Okay, I’ll follow the pointer one level deeper."
This behavior prevents your code from becoming cluttered with * symbols, which would quickly make simple logic difficult to read. It allows references to act like the values they point to while still respecting the strict ownership and borrowing rules you've learned. The compiler does the heavy lifting to ensure you are safely accessing the data without needing to manage the indirection manually.
Key Takeaway: Rust automatically resolves reference chains by dereferencing values as needed during method calls and field access, allowing you to use references as if they were the underlying data.