Trying to implement the Debug
trait for a custom type I stumbled upon the implementation for Vec<T>
. I have difficulties understanding how it works.
The implementation goes like this:
impl<T: fmt::Debug> fmt::Debug for Vec<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Debug::fmt(&**self, f)
}
}
I understand it calls the fmt
implementation for some other type. What I cannot understand is what type it is. I've tried to figure it out with the help of another question, and searching among the implementations of Debug
for something that looks appropriate (maybe something like &[T]
), but with no success.
What is the exact meaning of &**self
in this context? What implementation of Debug
is being called?
In cases like this, I find it useful to make the compiler tell you what the type is. Just cause a type error and let the compiler diagnostics do it for you. The easiest way is to try to assign your item to something of type ()
:
fn main() {
let v = &vec![1,2,3];
let () = v;
let () = &**v;
}
The errors are:
<anon>:3:9: 3:11 error: mismatched types:
expected `&collections::vec::Vec<_>`,
found `()`
(expected &-ptr,
found ()) [E0308]
<anon>:3 let () = v;
^~
<anon>:4:9: 4:11 error: mismatched types:
expected `&[_]`,
found `()`
(expected &-ptr,
found ()) [E0308]
<anon>:4 let () = &**v;
^~
Thus v
is a &collections::vec::Vec<_>
and &**v
is a &[_]
.
More detailed, Vec
has this:
impl<T> Deref for Vec<T> {
type Target = [T];
// ...
}
So, we dereference once to go from &Vec<T>
to a Vec<T>
, dereference again to get a [T]
, and then reference once to get a &[T]
.
[T]
has this:
impl<T> Debug for [T] {
fn fmt(&self, ...) ...;
}
However, when searching for an appropriate method to call, Rust will automatically attempt to dereference the target. That means we can find the method on [T]
from a &[T]
.
As corrected by Francis Gagné, Debug::fmt
takes &self
, so directly calling it with a &[T]
finds the matching implementation. No need for any automatic referencing or dereferencing.
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