I can't seem to figure out why:
let a = Box::new(5i32);
let _:() = *a;
tells me that the assigned type on the second line is i32
and not &i32
since Deref.deref()
(which I assume is being called at *a
), returns &T
.
Also, if I were to call deref()
myself:
let _:() = <Box<i32> as Deref>::deref(&a);
I get the expected &i32
.
Rust will also insert automatic dereferencing as part of deref coercion. This is a special coercion that can only convert from one reference type to another. For example, this is what lets you convert from String to &str by writing &x instead of &*x .
Trait std::ops::DerefUsed for immutable dereferencing operations, like *v . In addition to being used for explicit dereferencing operations with the (unary) * operator in immutable contexts, Deref is also used implicitly by the compiler in many circumstances. This mechanism is called ' Deref coercion'.
The dereference operator is also known as the indirection operator. Simply put, the dereferencing operator allows us to get the value stored in the memory address of a pointer. In Rust, we use the Deref trait to customize the behaviour of the dereferencing operator.
In general, &* means to first dereference ( * ) and then reference ( & ) a value. In many cases, this would be silly, as we'd end up at the same thing. However, Rust has deref coercions. Combined with the Deref and DerefMut traits, a type can dereference to a different type!
Dereferencing doesn't necessarily produce an (intermediate) value. Consider
let b = Box::new(1);
(*b).clone();
The method i32::clone()
is called with a &self
argument where the reference points to the value inside the box, not to a temporary value that could be produced by (*b)
.
The trait Deref
is part of implementing dereferencing (just like DerefMut
).
There is no corresponding trait to what *
can additionally do on a box: Move the inner value out and discard the box; this is colloquially called DerefMove
but remains a compiler-hardcoded box speciality at this point.
When the compiler sees (*a)
, it has to infer whether to use Deref
, DerefMut
or “DerefMove
”; it is inferred from how the expression is used: if you call a &self
method on the result, Deref
is used, for example.
Edited: Inherently copyable types (trait Copy
), use Deref
followed by copy instead of “DerefMove
”; this is then no longer resticted to Box, but works with all smart pointers.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With