The traits std::ops::Deref◹ and std::ops::DerefMut◹ are used for explicit dereference operations (immutable or mutable), like:
// immutable dereference
println!("{}", *a);
// mutable dereference
*a = <something>;
If a type T implements Deref<Target=U> or DerefMut<Target=U> like this:
impl<T> Deref for Something<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.value
}
}
impl<T> DerefMut for Something<T> {
type Target = T;
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.value
}
}
Any usage of
*ain immutable contexts are equivalent to*Deref::deref(&a), and*DerefMut::deref_mut(&mut a)in mutable contexts.Any values of type
&Twill be coerced to values of type&U, and values of type&mut Twill be coerced to values of type&mut U. Mutable references&mut Tcan also be coerced to immutable references&U, not the other way around, immutable references&Tcannot be coerced to mutable references&mut U.For example, because type
StringimplementedDeref<U=&str>◹, we can pass a reference&Stringto any function that takes a&str:fn hello(name: &str) { ... } let name: String = String::from("Huy"); hello(&name); // this worksType
Twill implicitly implement all the immutable (forDeref) and mutable (forDerefMut) methods of typeU.For example, when creating a wrapped type using tuple struct (see previous post), you cannot access any methods of the inner type from the wrapped type:
struct List(Vec<i32>); let list = List(vec![1, 2, 3]); println!("{}", list.last()); // 1 | struct List(Vec<i32>); // | ---------------------- // | | // | method `last` not found for this // | doesn't satisfy `List: Iterator` // ... // 5 | println!("{}", list.last()); //If you implement
DereforDerefMutfor the wrapped type, it will implicitly implement all the immutable or mutable methods from the inner type:impl Deref for List { type Target = Vec<i32>; fn deref(&self) -> &Self::Target { &self.0 } } println!("{}", list.first()); // Output: 1
You can read more about Deref and DerefMut in The Rust Programming Language Book◹, or in the documentation◹.