摘要:Rust 在很多地方使用了 traits, 从非常浅显的操作符重载, 到 Send, Sync 这种非常微妙的特性。

本文分享自华为云社区《Rust 内置 trait 解析:PartialEq 和 Eq》,原文作者:debugzhang

Rust 在很多地方使用了 traits, 从非常浅显的操作符重载, 到 Send, Sync 这种非常微妙的特性。一些 traits 是可以被自动派生的(你只需要写#[derive(Copy, Clone, PartialEq, Eq, Debug, Default, Hash, ...)] 就能得到一个神奇的实现, 它通常是对的。

PartialEq 和 Eq这两个 Traits 的名称实际上来自于抽象代数中的等价关系和局部等价关系,实际上两者的区别仅有一点,即是否在相等比较中是否满足反身性(Reflexivity)。

PartialEq

/// [`eq`]: PartialEq::eq
/// [`ne`]: PartialEq::ne
#[lang = "eq"]
#[stable(feature = "rust1", since = "1.0.0")]
#[doc(alias = "==")]
#[doc(alias = "!=")]
#[rustc_on_unimplemented(message = "can't compare `{Self}` with `{Rhs}`",label = "no implementation for `{Self} == {Rhs}`"
)]
pub trait PartialEq<Rhs: ?Sized = Self> {/// This method tests for `self` and `other` values to be equal, and is used/// by `==`.#[must_use]#[stable(feature = "rust1", since = "1.0.0")]fn eq(&self, other: &Rhs) -> bool;/// This method tests for `!=`.#[inline]#[must_use]#[stable(feature = "rust1", since = "1.0.0")]fn ne(&self, other: &Rhs) -> bool {!self.eq(other)}
}

如果我们想比较某个类型的两个值 x 和 y 是否相等(不等),例如:x == y (x != y),那么我们就必须为类型实现 PartialEq Trait。

PartialEq 可使用 #[derive] 来交由编译器实现,当一个 struct 在进行相等比较时,会对其中每一个字段进行比较;如果遇到枚举时,还会对枚举所拥有的数据进行比较。

我们也可以自己实现 PartialEq,实现时只需要实现判断是否相等的函数 fn eq(&self, other: &Self) -> bool ,Rust 会自动提供 fn ne(&self, other: &Self) -> bool。例子如下:

enum BookFormat {Paperback,Hardback,Ebook,
}struct Book {isbn: i32,format: BookFormat,
}impl PartialEq for Book {fn eq(&self, other: &Self) -> bool {self.isbn == other.isbn}
}

Eq

pub trait Eq: PartialEq<Self> {// this method is used solely by #[deriving] to assert// that every component of a type implements #[deriving]// itself, the current deriving infrastructure means doing this// assertion without using a method on this trait is nearly// impossible.//// This should never be implemented by hand.#[doc(hidden)]#[inline]#[stable(feature = "rust1", since = "1.0.0")]fn assert_receiver_is_total_eq(&self) {}
}

实现 Eq 的前提是已经实现了 PartialEq,因为实现 Eq 不需要额外的代码,只需要在实现了PartialEq 的基础上告诉编译器它的比较满足自反性就可以了。对于上面的例子只需要:#[derive(Eq)] 或 impl Eq for Book {}。

enum BookFormat {Paperback,Hardback,Ebook,
}struct Book {isbn: i32,format: BookFormat,
}impl PartialEq for Book {fn eq(&self, other: &Self) -> bool {self.isbn == other.isbn}
}impl Eq for Book {}

PartialEq 和 Eq

这两个 Traits 的名称实际上来自于抽象代数中的等价关系和局部等价关系。

等价关系(equivalence relation)即设 \displaystyle RR 是某个集合 \displaystyle AA 上的一个二元关系。若 \displaystyle RR 满足以下条件:

则称 \displaystyle RR 是一个定义在 \displaystyle AA 上的等价关系

并非所有的二元关系都是等价关系, Eq 和 PartialEq 的区别在于是否在相等比较中是否满足自反性,即 x == x。

例如对于浮点类型,Rust 只实现了 PartialEq 而没有实现 Eq,原因在于 NaN != Nan,不满足自反性。

Eq 相比 PartialEq 需要额外满足反身性,即 a == a,对于浮点类型,Rust 只实现了 PartialEq 而不是 Eq,原因就是 NaN != NaN。

Eq 和 Hash

当一个类型同时实现了 Eq 和 Hash 时,该类型满足下列特性:

k1 == k2 -> hash(k1) == hash(k2)

即,当两个 key 相等时,它们的哈希值必然相等。Rust 里的 HashMap 和 HashSet 都依赖该特性。

点击关注,第一时间了解华为云新鲜技术~

实践解析丨Rust 内置 trait:PartialEq 和 Eq相关推荐

  1. 安卓下微信内置浏览器视频出现解析错误

    原文地址 今天给客户做一个微信端的HTML5的动画页面,页面内有一个视频文件,今天上线,这是前提.刚上线不久,客户的服务器便不堪重负,为了解决问题,我们将该页面的媒体文件放在自己的服务器上.问题来了, ...

  2. Python培训分享:Python内置标准异常及其解析

    本期小编为大家带来的Python培训教程是关于"Python内置标准异常及其解析"的内容,我们都知道,在Python技术运作下,总会出现一些Python无法正常处理的程序时就会发生 ...

  3. python中json模块_Python使用内置json模块解析json格式数据的方法

    本文实例讲述了Python使用内置json模块解析json格式数据的方法.分享给大家供大家参考,具体如下: Python中解析json字符串非常简单,直接用内置的json模块就可以,不需要安装额外的模 ...

  4. python中f点flush是什么函数_Python文件操作及内置函数flush原理解析

    1.打开文件得到文件句柄并赋值给一个变量 2.通过句柄对文件进行操作 3.关闭文件 示例文件 '你好呀' 我是于超 嗯 再见 文件操作基本流程 f=open('chenli',encoding='ut ...

  5. 内置host_浏览器内置对象应用实践

    " 浏览器内置对象,我们每天都与其打交道,可能你并未全面的去了解过它.我们一起讨论下你有过哪些实践." 1. 什么是浏览器对象模型?(BOM :Browser Object Mod ...

  6. webserver接口_SpringBoot内置源码解析WebServer初始化过程

    WebServer 初始化过程 在上一节中 Spring Boot 初始化了 WebServer 对应的工厂类.同时,我们也知道对应 Web容器的WebServer实现类有:TomcatWebServ ...

  7. java自定义变量解析,Thymeleaf内置对象、定义变量、URL参数及标签自定义属性

    如标题所述,这篇文章主要讲述Thymeleaf中的内置对象(list解析.日期格式化.数字格式化等).定义变量.获取URL的参数和在页面标签中自定义属性的应用. 如果对Thymeleaf的基本使用.m ...

  8. 修改器内置脚本编写_Node.js 中实践 Redis Lua 脚本

    对别人的意见要表示尊重.千万别说:"你错了."--卡耐基 Lua 是一种轻量小巧的脚本语言,用标准 C 语言编写并以源代码形式开放,其设计目的是为了嵌入应用程序中,从而为应用程序提 ...

  9. HIve内置函数(functions)使用和解析

    函数分类: 二:函数解析 hive (default)> show functions; OK ! != 1.内置运算符 1.1关系运算符 1.2算术运算符 1.3逻辑运算符 1.4复杂类型函数 ...

最新文章

  1. 关于Fast Terrain Rendering Using Geometrical MipMapp
  2. 主流大数据系统在后台的层次角色及数据流向
  3. 网络营销推广软件教你学会单页面SEO优化技巧,轻松赢流量!
  4. php编译成二进制文件_JVM字节码文件概述
  5. matlab lu分解 l不是下三角,在MATLAB中执行LU分解而不进行旋转
  6. frame中src怎么设置成一个变量_自动格式化打印变量HMLog介绍
  7. 探讨float类型的数值,为什么两个float不能直接相等
  8. 分布式之数据库和缓存双写一致性方案解析!
  9. 如何将mysql文件导入MySQL_如何将mysql5的sql文件导入到mysql4?
  10. opnet平台中切换模块的理解——切换的建模
  11. Windows编程中引入winsock2.h后导致的错误解决
  12. 字符串的首地址做形参不能将变化传递回主函数
  13. 巴比特 | 元宇宙每日必读:红杉中国“雇”了一位虚拟员工,自称每秒可看百份商业计划书,期待时薪为0.68元...
  14. Zotero英文翻译插件安装教程
  15. 解决windows server 2003安装dhcp服务器的问题
  16. PD的CDM模型中的三种实体关系
  17. 大数据杀熟的背后 -- 浅谈用户画像
  18. KGE性能指标:MRR,MR,HITS@1,HITS@3,HITS@10
  19. alv edit and save all
  20. 参与微软Docs翻译

热门文章

  1. Java静态方法和实例方法 java中的数组作为形参传入
  2. Bootstrap列表组堆叠
  3. 单机启动nacos_SpringBoot集成Nacos的详细教程
  4. 堆积密度怎么做_长尾关键词怎么优化?这样布局关键词排名效率高
  5. pb 选中树形菜单节点_动态绑定树形菜单,并搜索节点展开
  6. sql 超时时间已到.在操作完成之前超时时间已过或服务器未响应.,sqlserver Timeout 时间已到。在操作完成之前超时时间已过或服务器未响应...
  7. spark 源码分析之十九 -- DAG的生成和Stage的划分
  8. 实现2个整形变量的交换
  9. 自制反汇编逆向分析工具 迭代第六版本 (一)
  10. 学习Android移植平台工具介绍的心得体会