In this lesson, you will learn how to make your custom smart pointers behave like standard references, allowing for ergonomic, seamless code.
The Problem: Manual Dereferencing
When you wrap a value in a custom struct—like a Box or a specialized container—you often want to access the inner value directly. Without Deref, you would be forced to constantly call a method like my_box.get_inner().value. This is clunky and breaks the illusion that your custom type is just a smart version of a normal reference.
Implementing Deref
The std::ops::Deref trait allows you to customize the behavior of the dereference operator (*). By implementing this trait, Rust will automatically "deref" your type whenever it encounters it in a context expecting the underlying type.
use std::ops::Deref;
struct MyWrapper<T>(T);
impl<T> Deref for MyWrapper<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
fn main() {
let x = MyWrapper(10);
// Even though x is a MyWrapper, we can treat it like an i32
assert_eq!(*x, 10);
}
Automatic Deref Coercion
The real magic happens with Deref Coercion. If you have a function that expects a &String, but you pass a &MyWrapper<String>, Rust will notice that MyWrapper implements Deref<Target = String>. It automatically calls deref() for you behind the scenes, turning your wrapper into a reference to the inner value. This is why you can pass a Box<String> to a function expecting &str.
Modifying Data with DerefMut
If you want to allow changing the inner data via dereferencing, you implement std::ops::DerefMut. This works just like Deref, but it requires that your type also implements Deref. It returns a mutable reference (&mut Self::Target), enabling you to modify the inner value directly using *my_wrapper = new_value;.
By using these traits, you ensure that your custom types play nicely with the rest of the ecosystem, hiding the "wrapper" logic from the user whenever possible.
Key Takeaway: The Deref and DerefMut traits allow your custom types to act like references, enabling automatic deref coercion that makes your APIs feel native and intuitive.