The dereferencing operator * is used to access the value pointed
to by a reference. Here is an example from
Dereferencing:
{
let a = 16;
let b = &a;
println!("{}", 16 == *b);
}true
()The Box structure is a kind of pointer/reference, and accepts too
the usage of the dereferencing operator * to access the original
value thanks to the implementation of the
Deref trait:
let a = 16;
let b = Box::new(a);
16 == *bCouldn't automatically determine type of variable `b`.
Please give it an explicit type.The Deref trait is implemented as following for a pointer type
Foo<T>:
use std::ops::Deref;
impl<T> Deref for Foo<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
// Returns a reference to the target
}
}The deref() method returns a reference to the original value of
type Target (i.e.: T), it does not actually dereference.
Instead, what happens in our example above with the *b line is the
following:
The compiler sees that
bis a type implementingDeref.It calls
b.deref()and gets a reference on the original value.It applies the dereferencing operator
*on this reference.
31.2.1Automatic Deref coercion¶
The Deref trait is implemented for multiple types in Rust. For
instance the String type implements the Deref trait to allow the
automatic conversion of &String into &str.
Let us see it in effect. First we create a function that accepts a
&str:
fn hello(name: &str) {
println!("Hello, {name}!");
}Let us suppose now that we have a String inside a Box:
let x = Box::new(String::from("Rust"));The following call works because:
The
Boximplementation of theDereftrait allows the compiler to convert&xinto a&String.The
Stringimplementation of theDereftrait allows the compiler to convert the&Stringinto a&str.
hello(&x);31.2.2Method access¶
Thanks to the Deref trait we can also access methods that are
defined inside the pointed objects.
Using this property, we can for instance call the to_uppercase()
method of str onto the Box object x:
x.to_uppercase()31.2.3DerefMut¶
There exists also a DerefMut trait that permits to dereference a mutable object.
Let us define a mutable Box object on a String:
let mut x = Box::new(String::from("Hello, "));We can call any method that modifies the internal string, like
push_str(), on x:
x.push_str("John!");Here is the result:
x