尝试实现 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)
}
}
我知道它调用了 fmt
其他类型的实现。我无法理解的是它是什么类型。我试图在 another question 的帮助下弄清楚, 并在 implementations of Debug
中搜索对于看起来合适的东西(可能像 &[T]
),但没有成功。
&**self
的确切含义是什么?在这种情况下? Debug
的执行情况正在调用?
最佳答案
在这种情况下,我发现让编译器告诉您类型是什么很有用。只需导致类型错误,让编译器诊断程序为您完成。最简单的方法是尝试将您的项目分配给类型为 ()
的东西:
fn main() {
let v = &vec![1,2,3];
let () = v;
let () = &**v;
}
错误是:
<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;
^~
因此 v
是 &collections::vec::Vec<_>
和 &**v
是 &[_]
.
更详细,Vec
有这个:
impl<T> Deref for Vec<T> {
type Target = [T];
// ...
}
因此,我们从 &Vec<T>
取消引用一次到 Vec<T>
, 取消引用再次 得到[T]
, 然后引用一次以获得 &[T]
.
[T]
有这个:
impl<T> Debug for [T] {
fn fmt(&self, ...) ...;
}
然而,当搜索一个合适的方法来调用时,Rust 会 automatically attempt to dereference目标。这意味着我们可以在 [T]
上找到该方法来自&[T]
.
作为corrected by Francis Gagné , Debug::fmt
需要 &self
, 所以直接用 &[T]
调用它找到匹配的实现。无需任何自动引用或取消引用。
关于reference - 了解 Vec<T> 的调试实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30261815/