自动取消引用和取消强制之间的关系是什么



经过一些讨论,我现在对auto-dereferencingderef 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&T&mut T。这就是为什么您可以将接收&mut self的方法直接调用为x.foo(),而不必编写(&mut x).foo()。对于候选列表中的每一种类型,编译器都会查找固有的方法和可见特征的方法。请参阅语言参考以了解更多详细信息。

被遗弃的胁迫是完全不同的。它只发生在强制站点,编译器在那里确切地知道要使用什么类型。如果遇到的实际类型与预期类型不同,编译器可以使用任何强制,包括取消引用强制,将实际类型转换为预期类型。可能的矫顽磁力列表包括未大小的矫顽力、指针弱化和取消引用矫顽力。有关更多详细信息,请参阅Nomicon中关于矫顽力的章节。

因此,这实际上是两种截然不同的机制——一种用于找到正确的方法,另一种用于在已知确切的类型时转换类型。第一种机制还自动引用接收器,这在强制中永远不会发生。

我认为去引用并不总是涉及去引用强制,但我不确定:去引用总是使用一些Deref::deref特性实现吗?

并不是每个取消引用都是取消引用强制。如果编写*x,则显式地取消引用x。相反,deref强制是由编译器隐式执行的,并且仅在编译器知道预期类型的地方执行。

去引用的语义取决于x的类型是指针类型,即引用还是原始指针。对于指针类型,*x表示x所指向的对象,而对于其他类型,*x等效于*Deref::deref(&x)(或其可变anlogue(。

如果是,T: Deref<Target = U> where T: &U的实现器是否内置在编译器中?

我不太确定你的语法应该是什么意思——它肯定不是有效的Rust语法——但我猜你在问编译器中是否内置了从&TT的取消围栏实例。如上所述,编译器中内置了指针类型(包括引用(的去引用,但在标准库中也有针对&TDeref的一揽子实现。这种一揽子实现对于泛型代码非常有用——否则特性绑定的T: Deref<Target = U>就不允许使用T = &U

最新更新