从书中的一节:
Deref强制将对实现Deref
trait的类型的引用转换为对另一个类型的引用。当我们将对特定类型的值的引用作为参数传递给函数或方法时,它会自动发生,而该函数或方法与函数或方法定义中的参数类型不匹配。
在下面的代码中,我试图找出bar
和From::from
之间的区别,这意味着一个编译,另一个不编译。
struct T;
struct U;
struct W;
impl From<&U> for T {
fn from(u: &U) -> T { T }
}
impl std::ops::Deref for W {
type Target = U;
fn deref(&self) -> &U {
&U
}
}
fn foo(_: T) {}
fn bar(_: &U) {}
fn main() {
let w = &W;
foo(T::from(w)); // error. "trait bound `T: From<&W>` not satisfied"
// bar(w); // okay
}
如果我显式输入From::<&U>::from(w)
,我可以让它编译。但我不希望必须这样做。即使T
有多个From
实现,一个类型只能deref()
到一个类型,所以编译器不是只有一个选项,尝试和deref传递的类型,然后看看From
实现是否存在的目标?
1条答案
按热度按时间eblbsuwk1#
不同之处在于
bar
是一个具体的函数,而T::from
不是,它是trait的任何实现之一,编译器首先必须找到正确的实现,但它发现From<&U>
没有实现,然后放弃。这里甚至没有关于deref强制的证明,因为编译器这样做的情况在这里都不适用。
我们还没有函数⇒我们没有目标类型⇒我们无法“匹配函数或方法定义中的参数类型”。