我试图编译以下代码以了解应用于引用的比较运算符的行为:
fn main() {
&1 == &2; // OK
&&1 == &&2; // OK
&1 == &mut 2; // OK
&mut(&1) == &(&mut 2); // OK
1 == &2; // Compilation Error
&1 == &&2; // Compilation Error
}
根据此结果,对于实现T
的类型PartialEq
,看来
T
s的引用,对T
s的引用的...是可比较的。==
两侧的引用数量必须相同。这些规则从何而来?规则1和2可以源自the semantics of comparison operators和反引用强制。考虑&1 == &mut 2
:
PartialEq::eq(&&1, &(&mut 2))
。&&1
通过反强制转换为&1
,因为&T
implements Deref<Target = T>
。&(&mut 2)
通过反强制转换为&2
,因为&mut T
implements Deref<Target = T>
。PartialEq::eq
实现的i32
的签名匹配。因此PartialEq::<i32>::eq(&1, &2)
得到了评估。但是,我不知道规则3的来源。我认为PartialEq::eq(&1, &&2)
被强制转换为PartialEq::eq(&1, &2)
,因为解引用强制被独立地应用于两个参数。
规则3的基本原理是什么?请在编译器中显示Rust或相应代码的书面语义?
答案 0 :(得分:1)
使用运算符时似乎没有发生反强制(我不确定为什么会这样),但是由于PartialEq
的实现,仍然可以使用借用。
从PartialEq
的Rust文档中可以看到以下实现:
impl<'a, 'b, A, B> PartialEq<&'b B> for &'a A
where
A: PartialEq<B> + ?Sized,
B: ?Sized,
如果存在类型B
和{{的A
实现,则声明有PartialEq
类型的借用实现和类型A
的借用。 1}}。
鉴于此定义,可以使用B
是因为&i32 == &i32
实现了i32
,并且鉴于以上暗示,这表明PartialEq
是为PartialEq
的借用而实现的。然后,这将导致递归的情况,即i32
起作用,因为为&&i32 == &&i32
实现了PartialEq
,因此鉴于上述暗示,&i32
也为PartialEq
实现了。>
由于此实现的定义,双方的借阅次数必须相同。