问题描述
经过一些讨论后,我现在对auto-dereferencing
和 deref coercion
的关系.
After some discussion, I'm now a little bit confused about the relation between auto-dereferencing
and deref coercion
.
似乎自动取消引用"一词适用仅当取消引用的目标是方法接收器时,而 似乎 术语取消引用强制"适用于函数参数和它需要的所有上下文.
It seems that the term "auto-dereferencing" applies only when the target to dereference is a method receiver,whereas it seems that the term "deref coercion" applies to function arguments and all contexts it needs to.
我认为解引用并不总是涉及解引用强制,但我不确定:解引用是否总是使用一些 Deref::deref
trait 实现?
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?
如果是,是T的实现者:Deref其中 T: &U
内置在编译器中?
If so, is the implementor of T: Deref<Target = U> where T: &U
built into the compiler?
最后,在编译器将 &&&&x
隐式转换为 &x
的所有情况下,使用术语autoderef"听起来很自然>:
Finally, it sounds natural to use the term "autoderef" in all the cases where the compiler implicitly transforms &&&&x
to &x
:
pub fn foo(_v: &str) -> bool {
false
}
let x="hello world";
foo(&&&&x);
这是社区的普遍共识吗?
Is this the general consensus of the community?
推荐答案
这两个案例之间的相似之处相当肤浅.
The parallels between the two cases are rather superficial.
在一个方法调用表达式中,编译器首先需要确定调用哪个方法.该决定基于接收器的类型.编译器构建候选接收器类型列表,其中包括通过重复取消引用接收器获得的所有类型,还包括所有类型 &T
和 &mut T
>T 遇到.这就是为什么您可以将接收 &mut self
的方法直接调用为 x.foo()
而不必编写 (&mut x).foo()
.对于候选列表中的每个类型,编译器然后查找固有方法和可见特征的方法.请参阅语言参考了解更多信息详情.
In a method call expression, the compiler first needs to determine which method to call. This decision is based on the type of the receiver. The compiler builds a list of candidate receiver types, which include all types obtained by repeatedly derefencing the receiver, but also &T
and &mut T
for all types T
encountered. This is the reason why you can call a method receiving &mut self
directly as x.foo()
instead of having to write (&mut x).foo()
. For each type in the candidate list, the compiler then looks up inherent methods and methods on visible traits. See the language reference for further details.
解引用强制是相当不同的.它只发生在强制转换站点,编译器确切地知道期望什么类型.如果遇到的实际类型与预期类型不同,编译器可以使用任何强制转换,包括取消引用强制转换,将实际类型转换为预期类型.可能的强制转换列表包括未调整大小的强制转换、指针弱化和取消引用强制转换.有关更多详细信息,请参阅 Nomicon 中的强制转换章节.
A deref coercion is rather different. It only occurs at a coercion site where the compiler exactly knows what type to expect. If the actual type encountered is different from the expected type, the compiler can use any coercion, including a deref coercion, to convert the actual type to the expected type. The list of possible coercions includes unsized coercions, pointer weakening and deref coercions. See the the chapter on coercions in the Nomicon for further details.
所以这实际上是两种完全不同的机制——一种用于找到正确的方法,一种用于在已经知道确切期望的类型时转换类型.第一种机制还自动引用接收者,这在强制中永远不会发生.
So these are really two quite different mechanisms – one for finding the right method, and one for converting types when it is already known what type exactly to expect. The first mechanism also automatically references the receiver, which can never happen in a coercion.
我认为解引用并不总是涉及解引用强制,但我不确定:解引用是否总是使用一些 Deref::deref
trait 实现?
并非每个解引用都是解引用强制.如果你写*x
,你明确取消引用x
.相比之下,解引用强制由编译器隐式执行,并且仅在编译器知道预期类型的地方执行.
Not every dereferencing is a deref coercion. If you write *x
, you explicitly dereference x
. A deref coercion in contrast is performed implicitly by the compiler, and only in places where the compiler knows the expected type.
解除引用的语义 取决于 x
的类型是否为 指针类型,即引用或原始指针.对于指针类型,*x
表示x
指向的对象,而对于其他类型*x
等价于*Deref::deref(&x)
(或它的可变类比).
The semantics of dereferencing depend on whether the type of x
is a pointer type, i.e. a reference or a raw pointer, or not. For pointer types, *x
denotes the object x
points to, while for other types *x
is equivalent to *Deref::deref(&x)
(or the mutable anlogue of this).
如果是,是T的实现者:Deref其中 T: &U
内置在编译器中?
我不太确定你的语法是什么意思——它肯定不是有效的 Rust 语法——但我猜你是在问是否将 &T
的实例取消引用到 T
内置于编译器中.如上所述,指针类型的解引用,包括引用,是内置在编译器中的,但也有一个 标准库中&T
的Deref
一揽子实现.这种全面的实现对于泛型代码很有用 - 特征绑定 T: Deref
否则将不允许 T = &U
.
I'm not quite sure what your syntax is supposed to mean – it's certainly not valid Rust syntax – but I guess you are asking whether derefencing an instance of &T
to T
is built into the compiler. As mentioned above, dereferencing of pointer types, including references, is built into the compiler, but there is also a blanket implementation of Deref
for &T
in the standard library. This blanket implementation is useful for generic code – the trait bound T: Deref<Target = U>
otherwise wouldn't allow for T = &U
.
这篇关于自动解引用和解引用强制之间有什么关系?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!