In Rust, smart pointers are data structures that act like pointers but also have additional metadata and capabilities. Examples include `Box<T>`, `Rc<T>`, and `Arc<T>`. When working with smart pointers, it's often desirable to be able to use the dereference operator (`*`) on them, just as you would with regular references (`&`). This is achieved through the `Deref` trait.
What is the Deref Trait?
The `Deref` trait, located in `std::ops::Deref`, allows you to customize the behavior of the dereference operator (`*`). Implementing this trait for a type `P` means that `*P` can be used to access the value that `P` 'points' to. The trait has one required associated type, `Target`, and one method, `deref`:
```rust
pub trait Deref {
type Target: ?Sized;
fn deref(&self) -> &Self::Target;
}
```
When you implement `Deref` for your smart pointer type, say `MyBox<T>`, and specify `Target = T`, calling `*my_box_instance` will effectively call `*my_box_instance.deref()`, giving you a reference to the inner `T` value.
Deref Coercion
One of the most powerful features enabled by the `Deref` trait is "Deref Coercion". Deref coercion is a convenience that Rust performs automatically when it sees a reference to a type that implements `Deref`. Specifically:
* If you have a type `P` that implements `Deref<Target = T>`, then a value of type `&P` can be automatically coerced into a value of type `&T`.
* This also applies transitively: if `T` itself implements `Deref<Target = U>`, then `&P` can be coerced to `&T`, and then to `&U`.
This automatic conversion happens in several contexts:
1. When calling methods: If a method `foo` is defined for `T`, but not for `P`, then `p.foo()` will work if `P` implements `Deref<Target = T>` (or `DerefMut` for mutable methods), as `p` will be dereferenced to `&T` (or `&mut T`) before the method call.
2. When passing arguments to functions: If a function expects an argument of type `&T`, you can pass an argument of type `&P` (where `P` implements `Deref<Target = T>`) and Rust will automatically dereference it.
Benefits of Deref Coercion
* Convenience: It allows smart pointers to be used almost interchangeably with regular references, making code cleaner and more ergonomic. You don't have to manually call `.deref()` or repeatedly use `*`.
* Polymorphism: Functions designed to work with references to a base type can seamlessly accept smart pointers to that type.
* Integration: It helps smart pointers integrate well with existing Rust code that expects references.
DerefMut Trait
For mutable smart pointers, there's also the `DerefMut` trait, which allows the `*` operator to yield a mutable reference (`&mut T`). Its signature is `fn deref_mut(&mut self) -> &mut Self::Target;`.








Treating Smart Pointers Like Regular References with the Deref Trait