自动解引用和解引用强制之间有什么关系?
What is the relation between auto-dereferencing and deref coercion?
经过一些,我现在对auto-dereferencing
和deref coercion
之间的关系有点困惑。
术语 "auto-dereferencing" 仅适用于取消引用的目标是方法接收器时,
而 it seems 术语 "deref coercion" 适用于函数参数及其需要的所有上下文。
我认为解引用并不总是涉及解引用强制,但我不确定:解引用是否总是使用某些 Deref::deref
特征实现?
如果是,T: Deref<Target = U> where T: &U
的实现者是否内置于编译器中?
最后,在编译器将 &&&&x
隐式转换为 &x
的所有情况下,使用术语 "autoderef" 听起来很自然:
pub fn foo(_v: &str) -> bool {
false
}
let x="hello world";
foo(&&&&x);
这是社区的普遍共识吗?
这两个案例之间的相似之处相当肤浅。
在方法调用表达式中,编译器首先需要确定调用哪个方法。该决定基于接收器的类型。编译器构建候选接收器类型列表,其中包括通过重复取消引用接收器获得的所有类型,但也包括 &T
和 &mut T
遇到的所有类型 T
。这就是为什么您可以直接将接收 &mut self
的方法调用为 x.foo()
而不必编写 (&mut x).foo()
的原因。对于候选列表中的每个类型,编译器然后查找固有方法和可见特征的方法。有关详细信息,请参阅 language reference。
取消引用强制转换非常不同。它只发生在强制站点,编译器确切地知道期望的类型。如果遇到的实际类型与预期类型不同,编译器可以使用任何强制转换(包括 deref 强制转换)将实际类型转换为预期类型。可能的强制转换列表包括未定大小的强制转换、指针弱化和取消引用强制转换。有关详细信息,请参阅 chapter on coercions in the Nomicon。
所以这实际上是两种截然不同的机制——一种用于寻找正确的方法,另一种用于在已经知道确切期望的类型时转换类型。第一种机制还自动 引用 接收者,这在强制转换中永远不会发生。
I thought that a dereference does not always involve deref coercion, but I'm not sure: does dereferencing always use some Deref::deref
trait implementation?
并非每个取消引用都是取消引用强制。如果你写 *x
,你 显式 取消引用 x
。相反,deref coercion 由编译器隐式执行,并且仅在编译器知道预期类型的地方执行。
semantics of dereferencing取决于x
的类型是指针类型,即引用还是原始指针。对于指针类型,*x
表示 x
指向的对象,而对于其他类型,*x
等同于 *Deref::deref(&x)
(或 this 的可变类比)。
If so, is the implementor of T: Deref<Target = U> where T: &U
built into the compiler?
我不太确定你的语法应该是什么意思——它肯定不是有效的 Rust 语法——但我猜你是在问是否将 &T
的实例取消引用到 T
进入编译器。如上所述,指针类型的解引用,包括引用,是编译器内置的,但标准库中也有一个blanket implementation of Deref
for &T
。这种一揽子实现对通用代码很有用——特征绑定 T: Deref<Target = U>
否则不允许 T = &U
.
经过一些auto-dereferencing
和deref coercion
之间的关系有点困惑。
我认为解引用并不总是涉及解引用强制,但我不确定:解引用是否总是使用某些 Deref::deref
特征实现?
如果是,T: Deref<Target = U> where T: &U
的实现者是否内置于编译器中?
最后,在编译器将 &&&&x
隐式转换为 &x
的所有情况下,使用术语 "autoderef" 听起来很自然:
pub fn foo(_v: &str) -> bool {
false
}
let x="hello world";
foo(&&&&x);
这是社区的普遍共识吗?
这两个案例之间的相似之处相当肤浅。
在方法调用表达式中,编译器首先需要确定调用哪个方法。该决定基于接收器的类型。编译器构建候选接收器类型列表,其中包括通过重复取消引用接收器获得的所有类型,但也包括 &T
和 &mut T
遇到的所有类型 T
。这就是为什么您可以直接将接收 &mut self
的方法调用为 x.foo()
而不必编写 (&mut x).foo()
的原因。对于候选列表中的每个类型,编译器然后查找固有方法和可见特征的方法。有关详细信息,请参阅 language reference。
取消引用强制转换非常不同。它只发生在强制站点,编译器确切地知道期望的类型。如果遇到的实际类型与预期类型不同,编译器可以使用任何强制转换(包括 deref 强制转换)将实际类型转换为预期类型。可能的强制转换列表包括未定大小的强制转换、指针弱化和取消引用强制转换。有关详细信息,请参阅 chapter on coercions in the Nomicon。
所以这实际上是两种截然不同的机制——一种用于寻找正确的方法,另一种用于在已经知道确切期望的类型时转换类型。第一种机制还自动 引用 接收者,这在强制转换中永远不会发生。
I thought that a dereference does not always involve deref coercion, but I'm not sure: does dereferencing always use some
Deref::deref
trait implementation?
并非每个取消引用都是取消引用强制。如果你写 *x
,你 显式 取消引用 x
。相反,deref coercion 由编译器隐式执行,并且仅在编译器知道预期类型的地方执行。
semantics of dereferencing取决于x
的类型是指针类型,即引用还是原始指针。对于指针类型,*x
表示 x
指向的对象,而对于其他类型,*x
等同于 *Deref::deref(&x)
(或 this 的可变类比)。
If so, is the implementor of
T: Deref<Target = U> where T: &U
built into the compiler?
我不太确定你的语法应该是什么意思——它肯定不是有效的 Rust 语法——但我猜你是在问是否将 &T
的实例取消引用到 T
进入编译器。如上所述,指针类型的解引用,包括引用,是编译器内置的,但标准库中也有一个blanket implementation of Deref
for &T
。这种一揽子实现对通用代码很有用——特征绑定 T: Deref<Target = U>
否则不允许 T = &U
.