【发布时间】:2018-07-04 08:23:56
【问题描述】:
我尝试编译以下代码以了解应用于引用的比较运算符的行为:
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
}
根据这个结果,对于实现PartialEq的类型T,看来
-
Ts 的引用,Ts 的引用的引用,...具有可比性。 - 可以混合使用共享引用和可变引用。
-
==两边的引用数量必须相同。
这些规则从何而来?规则 1 和 2 可以从 the semantics of comparison operators 和 deref 强制导出。考虑&1 == &mut 2:
- 编译器将表达式解释为
PartialEq::eq(&&1, &(&mut 2))。 - 第一个参数
&&1通过 deref 强制转换为&1,因为&TimplementsDeref<Target = T>。 - 第二个参数
&(&mut 2)通过 deref 强制转换为&2,因为&mut TimplementsDeref<Target = T>。 - 现在两个参数的类型都与
PartialEq::eq的签名匹配,该签名由i32实现。所以PartialEq::<i32>::eq(&1, &2)被评估了。
但是,我不明白规则 3 的来源。我认为 PartialEq::eq(&1, &&2) 被强制转换为 PartialEq::eq(&1, &2) 因为 deref coercion 独立应用于两个参数。
规则 3 的基本原理是什么?请显示 Rust 的文档语义或编译器中的相应代码?
【问题讨论】:
-
更令人好奇的是,“手工”
PartialEq实现实际上可以处理这种情况:playground。
标签: rust