首页 > 解决方案 > 为什么 1 == &2 不能编译?

问题描述

我尝试编译以下代码以了解应用于引用的比较运算符的行为:

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,似乎

  1. s 的引用T,s 的引用T,... 的引用是可比较的。
  2. 共享和可变引用可以混合使用。
  3. 两边的引用数量==必须相同。

这些规则从何而来?规则 1 和 2 可以从比较运算符和 deref 强制的语义中得出。考虑&1 == &mut 2

  1. 该表达式被PartialEq::eq(&&1, &(&mut 2))编译器解释为。
  2. 第一个参数&&1变成&1了 deref coercion 因为&TimplementsDeref<Target = T>
  3. 第二个参数&(&mut 2)变成&2了 deref coercion 因为&mut TimplementsDeref<Target = T>
  4. PartialEq::eq现在,两个参数的类型都与implemented by的签名相匹配i32。如此PartialEq::<i32>::eq(&1, &2)评价。

但是,我不明白规则 3 的来源。我认为PartialEq::eq(&1, &&2)是强制的,PartialEq::eq(&1, &2)因为 deref 强制独立应用于两个参数。

规则 3 的基本原理是什么?请在编译器中显示 Rust 的文档语义或适当的代码?

标签: rust

解决方案


使用运算符时似乎没有发生 deref 强制(我不确定为什么会这样),但是由于PartialEq.

PartialEq以下实现的 Rust 文档可以看出:

impl<'a, 'b, A, B> PartialEq<&'b B> for &'a A 
where
    A: PartialEq<B> + ?Sized,
    B: ?Sized, 

这表明存在类型借用和类型B借用A的实现,如果存在PartialEqfor type Aand的实现B

给定这个定义,&i32 == &i32 可以使用因为i32implementsPartialEq并且给定上面的 impl,这个指令PartialEq是为借用i32s 实现的。这会导致递归情况&&i32 == &&i32有效,因为PartialEq是为&i32所以实现的,因为上面的 implPartialEq也是为 实现的&&i32

由于此实现的定义,双方的借用次数必须相同。


推荐阅读