Per this question,如果您在类型
Deref<Target = T>
上实现 U
,则可以在类型 T
的表达式上调用 impl T { ... }
的固有方法(在 U
中定义的方法),但是您无法调用为 T
定义的特征的方法。
pub struct Thing(String);
impl Thing {
pub fn new(s: impl Into<String>) -> Self {
Self(s.into())
}
}
但是,当我尝试将其与方法调用解析中的 Rust 参考部分 进行比较时,我感到困惑。它说找到可用方法的步骤是:
通过重复取消引用接收者表达式的类型来获取[候选接收者类型列表],...然后,对于每个候选类型 T,在以下位置搜索具有该类型接收者的可见方法:
- T 的固有方法(直接在 T 上实现的方法)。
- T 实现的可见特征提供的任何方法。
第 2 部分听起来应该与我链接的问题的答案不一致。
当我尝试这个时(游乐场:
use std::ops::Deref;
struct Thing(String);
impl Thing {
pub fn new(s: String) -> Self {
Self(s)
}
}
impl Deref for Thing {
type Target = String;
fn deref(&self) -> &String {
&self.0
}
}
fn main() {
let thing = Thing::new(" jup ".to_string());
// I can call trim on a Thing, because of deref-coercion.
println!("{}", thing.trim());
// I cannot call fmt, because that is a trait implemented on the inner type.
// println!("{}", thing);
// But, I can call clone...?
println!("{}", thing.clone());
}
我确实发现我的外部类型的行为不像它实现了 Display,尽管内部类型确实实现了 Display,但我确实发现它的行为就像它实现了
Clone
。
我在这里不明白什么?我引用的 Rust 参考部分似乎应该在我调用
String
对象上的方法时找到 Thing
作为候选类型,并且我相信 Clone
和 Display
都是“由 String
实现的可见特征”。然而我链接的问题似乎表明两者都不应该可用(尽管它没有说完全相同的事情 - 它只是说Thing
不实现Clone
或Display
,也许那是不同的)能够在类型 Thing
) 的表达式上调用这些特征的方法。
等等,我想我可能通过盯着我的问题一段时间就明白了
虽然它并没有说完全相同的事情 - 它只是说 Thing 没有实现 Clone 或 Display,也许这与能够在 Thing 类型的表达式上调用这些特征的方法不同)
println!("{}", thing);
println!("{}", thing.clone());
这些确实不是一回事!在第一个中(大概我还没有真正阅读过
println!
的实现),我试图将 thing
传递给一个具有必须实现 Display
约束的函数。根据链接的问题,它没有实现Display
。
在第二个中,我在
thing
上调用一个方法。根据 Rust 参考,这是有效的!
所以我总结一下:你可以调用内部类型实现的特征上的方法,但你的外部类型实际上并没有实现这些特征。
将保留这个问题,因为我很可能仍然弄错了。