了解Vec <T>的Debug实现

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正在调用什么实现?

She*_*ter 8

在这种情况下,我发现让编译器告诉你类型是什么很有用.只是导致类型错误,让编译器诊断为您完成.最简单的方法是尝试将您的项目分配给某种类型():

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]找到匹配的实现.无需任何自动引用或解除引用.

  • 我不认为有任何自动解除引用(或自动引用),因为`fmt :: Debug :: fmt()`通过引用接受`self`,即它需要一个`&[T]`,并给出它一个`&[T]`. (2认同)