tor*_*o2k 5 reference dereference rust
试图Debug为自定义类型实现特性我偶然发现了它的实现Vec<T>.我很难理解它是如何工作的.
实现如下:
impl<T: fmt::Debug> fmt::Debug for Vec<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Debug::fmt(&**self, f)
}
}
Run Code Online (Sandbox Code Playgroud)
据我所知,它调用了fmt其他类型的实现.我无法理解的是它是什么类型.我试图在另一个问题的帮助下弄清楚它,并在实现中Debug搜索看起来合适的东西(可能是类似的东西&[T]),但没有成功.
&**self在这种情况下,确切含义是什么?Debug正在调用什么实现?
在这种情况下,我发现让编译器告诉你类型是什么很有用.只是导致类型错误,让编译器诊断为您完成.最简单的方法是尝试将您的项目分配给某种类型():
fn main() {
let v = &vec![1,2,3];
let () = v;
let () = &**v;
}
Run Code Online (Sandbox Code Playgroud)
错误是:
<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;
^~
Run Code Online (Sandbox Code Playgroud)
因此v是一个&collections::vec::Vec<_>而且&**v是一个&[_].
更详细,Vec有这个:
impl<T> Deref for Vec<T> {
type Target = [T];
// ...
}
Run Code Online (Sandbox Code Playgroud)
所以,我们取消引用一次从&Vec<T>a到Vec<T>de,dereference 再次得到a [T],然后引用一次得到a &[T].
[T] 有这个:
impl<T> Debug for [T] {
fn fmt(&self, ...) ...;
}
Run Code Online (Sandbox Code Playgroud)
但是,在搜索适当的调用方法时,Rust会自动尝试取消引用目标.这意味着我们可以[T]从a 找到方法&[T].
正如弗朗西斯加涅修正,Debug::fmt需要&self,因此直接与调用它&[T]找到匹配的实现.无需任何自动引用或解除引用.