Understanding Debug Implementation for Vec <T>
Trying to implement the Debug flag for a custom type, I came across an implementation for Vec<T> . I find it hard to understand how this works.
The implementation is as follows:
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 that it calls the fmt implementation for another type. What I canโt understand is the type. I tried to figure this out with a different question and search in the Debug implementations for something suitable (maybe something like &[T] ), but without success.
What is the exact meaning of &**self in this context? What implementation of Debug is called?
In such cases, I find it useful to make a compiler to find out what type it is. Just print a type error, and let the compiler diagnostics do it for you. The easiest way is to try to assign your element to something like () :
fn main() { let v = &vec![1,2,3]; let () = v; let () = &**v; } Errors:
<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; ^~ So v is &collections::vec::Vec<_> , and &**v is &[_] .
In more detail, Vec has the following:
impl<T> Deref for Vec<T> { type Target = [T]; // ... } So, we search once to go from &Vec<T> to Vec<T> , dereference again to get [T] , and then reference once to get &[T] .
[T] has the following meaning:
impl<T> Debug for [T] { fn fmt(&self, ...) ...; } However, when looking for a suitable method to call, Rust will automatically try to dereference the target. This means that we can find a method on [T] from a &[T] .
As fixed by Francis Gagnรฉ , Debug::fmt accepts &self , so directly accessing it with &[T] finds a matching implementation. No need for any automatic links or dereferences.