实践解析丨Rust 内置 trait:PartialEq 和 Eq
摘要: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相关推荐
- 安卓下微信内置浏览器视频出现解析错误
原文地址 今天给客户做一个微信端的HTML5的动画页面,页面内有一个视频文件,今天上线,这是前提.刚上线不久,客户的服务器便不堪重负,为了解决问题,我们将该页面的媒体文件放在自己的服务器上.问题来了, ...
- Python培训分享:Python内置标准异常及其解析
本期小编为大家带来的Python培训教程是关于"Python内置标准异常及其解析"的内容,我们都知道,在Python技术运作下,总会出现一些Python无法正常处理的程序时就会发生 ...
- python中json模块_Python使用内置json模块解析json格式数据的方法
本文实例讲述了Python使用内置json模块解析json格式数据的方法.分享给大家供大家参考,具体如下: Python中解析json字符串非常简单,直接用内置的json模块就可以,不需要安装额外的模 ...
- python中f点flush是什么函数_Python文件操作及内置函数flush原理解析
1.打开文件得到文件句柄并赋值给一个变量 2.通过句柄对文件进行操作 3.关闭文件 示例文件 '你好呀' 我是于超 嗯 再见 文件操作基本流程 f=open('chenli',encoding='ut ...
- 内置host_浏览器内置对象应用实践
" 浏览器内置对象,我们每天都与其打交道,可能你并未全面的去了解过它.我们一起讨论下你有过哪些实践." 1. 什么是浏览器对象模型?(BOM :Browser Object Mod ...
- webserver接口_SpringBoot内置源码解析WebServer初始化过程
WebServer 初始化过程 在上一节中 Spring Boot 初始化了 WebServer 对应的工厂类.同时,我们也知道对应 Web容器的WebServer实现类有:TomcatWebServ ...
- java自定义变量解析,Thymeleaf内置对象、定义变量、URL参数及标签自定义属性
如标题所述,这篇文章主要讲述Thymeleaf中的内置对象(list解析.日期格式化.数字格式化等).定义变量.获取URL的参数和在页面标签中自定义属性的应用. 如果对Thymeleaf的基本使用.m ...
- 修改器内置脚本编写_Node.js 中实践 Redis Lua 脚本
对别人的意见要表示尊重.千万别说:"你错了."--卡耐基 Lua 是一种轻量小巧的脚本语言,用标准 C 语言编写并以源代码形式开放,其设计目的是为了嵌入应用程序中,从而为应用程序提 ...
- HIve内置函数(functions)使用和解析
函数分类: 二:函数解析 hive (default)> show functions; OK ! != 1.内置运算符 1.1关系运算符 1.2算术运算符 1.3逻辑运算符 1.4复杂类型函数 ...
最新文章
- 关于Fast Terrain Rendering Using Geometrical MipMapp
- 主流大数据系统在后台的层次角色及数据流向
- 网络营销推广软件教你学会单页面SEO优化技巧,轻松赢流量!
- php编译成二进制文件_JVM字节码文件概述
- matlab lu分解 l不是下三角,在MATLAB中执行LU分解而不进行旋转
- frame中src怎么设置成一个变量_自动格式化打印变量HMLog介绍
- 探讨float类型的数值,为什么两个float不能直接相等
- 分布式之数据库和缓存双写一致性方案解析!
- 如何将mysql文件导入MySQL_如何将mysql5的sql文件导入到mysql4?
- opnet平台中切换模块的理解——切换的建模
- Windows编程中引入winsock2.h后导致的错误解决
- 字符串的首地址做形参不能将变化传递回主函数
- 巴比特 | 元宇宙每日必读:红杉中国“雇”了一位虚拟员工,自称每秒可看百份商业计划书,期待时薪为0.68元...
- Zotero英文翻译插件安装教程
- 解决windows server 2003安装dhcp服务器的问题
- PD的CDM模型中的三种实体关系
- 大数据杀熟的背后 -- 浅谈用户画像
- KGE性能指标:MRR,MR,HITS@1,HITS@3,HITS@10
- alv edit and save all
- 参与微软Docs翻译
热门文章
- Java静态方法和实例方法 java中的数组作为形参传入
- Bootstrap列表组堆叠
- 单机启动nacos_SpringBoot集成Nacos的详细教程
- 堆积密度怎么做_长尾关键词怎么优化?这样布局关键词排名效率高
- pb 选中树形菜单节点_动态绑定树形菜单,并搜索节点展开
- sql 超时时间已到.在操作完成之前超时时间已过或服务器未响应.,sqlserver Timeout 时间已到。在操作完成之前超时时间已过或服务器未响应...
- spark 源码分析之十九 -- DAG的生成和Stage的划分
- 实现2个整形变量的交换
- 自制反汇编逆向分析工具 迭代第六版本 (一)
- 学习Android移植平台工具介绍的心得体会