经过discussion之后,我对auto-dereferencing
和deref coercion
之间的关系有些困惑。
It seems,术语“自动取消引用”仅在要取消引用的目标是方法接收者时适用, 而it seems中的“反强制”一词适用于函数自变量及其所需的所有上下文。
我认为取消引用并不总是涉及强制取消引用,但是我不确定:取消引用是否总是使用某些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);
这是社区的普遍共识吗?
答案 0 :(得分:7)
这两种情况之间的相似之处很肤浅。
在方法调用表达式中,编译器首先需要确定要调用的方法。该决定基于接收器的类型。编译器将构建候选接收器类型的列表,其中包括通过反复取消引用接收器而获得的所有类型,但还包括遇到的所有类型&T
的{{1}}和&mut T
。这就是为什么您可以调用直接将T
接收为&mut self
的方法而不必编写x.foo()
的原因。对于候选列表中的每种类型,编译器随后会查找固有方法以及基于可见特征的方法。有关更多详细信息,请参见language reference。
反强制具有很大的不同。它仅发生在胁迫站点上,在该站点上编译器完全知道期望的类型。如果遇到的实际类型与预期类型不同,则编译器可以使用任何强制(包括deref强制)将实际类型转换为预期类型。可能的强制列表包括未定大小的强制,指针减弱和反强制。有关更多详细信息,请参见chapter on coercions in the Nomicon。
因此,实际上这是两种截然不同的机制–一种用于找到正确方法的机制,一种用于在已经知道确切期望哪种类型的情况下转换类型。第一种机制还会自动引用接收者,这种情况在强制转换中永远不会发生。
我认为取消引用并不总是涉及强制取消引用,但是我不确定:取消引用是否总是使用某些
(&mut x).foo()
特性实现?
并非每个取消引用都是取消引用强制。如果您写Deref::deref
,则会明确地取消引用*x
。相反,deref 强制由编译器隐式执行,并且仅在编译器知道预期类型的地方执行。
semantics of dereferencing取决于x
的类型是指针类型,即引用还是原始指针。对于指针类型,x
表示对象*x
指向的对象,而对于其他类型,x
等效于*x
(或该变量的类似物)。
如果是,
*Deref::deref(&x)
的实现者是否内置在编译器中?
我不太确定您的语法是什么意思-这肯定不是有效的Rust语法-但我想您是在问是否将T: Deref<Target = U> where T: &U
的实例取消引用到&T
中编译器。如上所述,对指针类型(包括引用)的取消引用已内置到编译器中,但标准库中也有一个blanket implementation of Deref
for &T
。这种通用的实现对通用代码很有用-特质绑定T
,否则将不允许T: Deref<Target = U>
。