You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust中==运算符比较需解引用而eq()方法不需要的原因

问题复现
use std::cmp::{Eq, PartialEq};
struct X{}
struct Y {}
impl PartialEq<Y> for X{
    fn eq(&self, rhs: &Y)->bool{
        true
    }
}

impl PartialEq for X{
    fn eq(&self, rhs: &X)->bool{
        true
    }
}

impl Eq for X {}

fn main() {
    let x = X{};
    let y = Y{};
    
    let f1 = |y: &Y| x == *y;
    let f2 = |y: &Y| x.eq(y);
    
}

上述代码中,使用==比较时需要手动对&Y类型的参数y做解引用,直接调用eq方法则不需要,两者差异的核心原因是语法规则不同。

核心规则说明
  • ==运算符的固定脱糖逻辑:a == b 会被编译器直接展开为 PartialEq::eq(&a, &b),编译器只会机械地给左右两个操作数各加一层引用,不会自动调整引用层级、也不会做自动解引用适配。
    闭包参数y是&Y类型,如果直接写x == y,展开后第二个参数类型是&&Y,但你只为X实现了PartialEq<Y>,对应的eq方法要求第二个参数是&Y,类型不匹配就会编译失败。只有写x == *y时,右操作数是Y类型,展开后自动加引用得到&Y,才能匹配方法签名。
  • 点号方法调用的自动适配逻辑:直接调用x.eq(y)走的是Rust的点号方法调用流程,点号有专门的类型适配机制:编译器会根据方法签名自动插入必要的取引用、解引用操作,让传入的参数匹配方法要求的类型。你传入的y本身就是&Y类型,和eq方法的参数要求完全一致,不需要任何额外操作,自然不需要手动解引用。

入门材料中常简化描述为"==等价于调用eq方法",这个说法省略了运算符的固定脱糖规则,很容易造成误解,两者并不是完全等价的语法糖。

内容的提问来源于stack exchange,提问作者mkmostafa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 22:33:22