【Rust中级教程】2.2. API设计原则之不意外性(unsurprising) Pt.2:实现Clone、Default、PartialEq、PartialOrd、Hash、Eq和Ord

发布时间:2026/9/12 18:42:55

【Rust中级教程】2.2. API设计原则之不意外性(unsurprising) Pt.2:实现Clone、Default、PartialEq、PartialOrd、Hash、Eq和Ord 2.2. API设计原则之不意外性(unsurprising) Pt.2实现Clone、Default、PartialEq、PartialOrd、Hash、Eq和Ord2.2.1. 建议实现Clonetrait和DefaulttraitClonetraitRust的Clonetrait允许实现者通过clone方法显式创建自身的深拷贝以区别于Copytrait提供的按值复制。看一个Clone例子#[derive(Debug, Clone)] struct Person { name: String, age: u32, } impl Person { fn new(name: String, age: u32) - Self { Self { name, age } } } fn main() { let person1 Person::new(John.to_owned(), 25); let person2 person1.clone(); println!({:?}, person1); println!({:?}, person2); }Person这个结构体实现了Clonetrait主函数中person2克隆了person1的数据因为它实现了Clone输出Person { name: John, age: 25 } Person { name: John, age: 25 }DefaulttraitRust的Defaulttrait允许类型定义一个默认值通过default()方法返回该类型的默认实例。看一个Default的例子#[derive(Default)] struct Point { x: i32, y: i32, } fn main() { let p Point::default(); println!(Point is at ({}, {}), p.x, p.y); }输出Point is at (0, 0)2.2.2. 建议实现PartialEq、PartialOrd、Hash、Eq和OrdtraitPartialEqtraitPartialEq提供和!操作符支持允许自定义类型进行部分相等性比较看个例子#[derive(Debug, PartialEq)] struct Point { x: i32, y: i32, } fn main() { let point1: Point Point { x: 1, y: 2 }; let point2: Point Point { x: 1, y: 2 }; let point3: Point Point { x: 3, y: 4 }; println!(point1 point2: {}, point1 point2); println!(point1 point3: {}, point1 point3); }通过实现PartialEq我们就可以实现比较结构体是否相等的操作输出point1 point2: true point1 point3: falsePartialOrd、PartialEq、Eq、OrdtraitPartialOrd提供、、和操作符支持允许自定义类型进行部分排序比较可能存在无法比较的情况Eq是PartialEq的更严格版本要求相等性满足自反性a a总是true。实现Eq必须要先实现PartialEq。Ord是PartialOrd的更严格版本要求实现全序关系使类型支持完整的排序逻辑如BTreeMap、BTreeSet 。实现Ord必须要先实现PartialOrd。看个例子use std::collections::BTreeMap; #[derive(Debug, PartialEq, PartialOrd, Eq, Ord, Clone)] struct Person { name: String, age: u32, } fn main() { let mut ages BTreeMap::new(); let person1 Person { name: String::from(Alice), age: 25, }; let person2 Person { name: String::from(Bob), age: 30, }; let person3 Person { name: String::from(Charlie), age: 20, }; ages.insert(person1.clone(), Alices Age); ages.insert(person2.clone(), Bobs Age); ages.insert(person3.clone(), Charlies Age); for (person, description) in ages { println!({}: {} - {:?}, person.name, person.age, description); } }BTreeMap实现了有序存储。它需要根据键的值来排序所以它要求键类型必须实现了Ord全局比较用于排序和Eq用于判断键是否相等。实现Ord又需要先实现PartialOrd实现Eq有需要先实现PartialEqHashtraitHash允许类型实现hash()方法以支持HashMap、HashSet等哈希集合。Hashtrait 本身并不以Eq为超 trait但哈希集合要求K: Eq Hash且相等的值必须产生相同的哈希。所以在实践中只要类型会用作哈希表/集合的键就应一并实现PartialEq和Eq。看个例子use std::collections::HashSet; use std::hash::{Hash, Hasher}; #[derive(Debug, PartialEq, Eq, Clone)] struct Person { name: String, age: u32, } impl Hash for Person { fn hashH: Hasher(self, state: mut H) { self.name.hash(state); self.age.hash(state); } } fn main() { let mut persons HashSet::new(); let person1 Person { name: Alice.to_string(), age: 25, }; let person2 Person { name: Bob.to_string(), age: 30, }; let person3 Person { name: Charlie.to_string(), age: 20, }; persons.insert(person1.clone()); persons.insert(person2.clone()); persons.insert(person3.clone()); println!(Persons: {:#?}, persons); }HashSet用于存储唯一的元素集合而HashMap用于存储键值对。输出Persons: { Person { name: Bob, age: 30, }, Person { name: Charlie, age: 20, }, Person { name: Alice, age: 25, }, }Eq与PartialEq、Ord与PartialOrdEq相对于PartialEq、Ord相对于PartialOrd都有额外的语义要求。只应在这些语义适用你的类型时才实现它们。我们看一下Eq相对于PartialEq的额外语义-自反性Reflexivity对于所有a必须有a a恒成立PartialEq本身已要求对称性和传递性Eq是“相等性也自反”的标记因此不存在诸如f32::NAN ! f32::NAN这类“部分相等”。我们看一下Ord相对于PartialOrd的额外语义-全序 / 可比性对所有a和ba b、a b、a b恰好成立其一等价地partial_cmp从不返回None-自反性Reflexivity对于所有a必须有a a和a a恒成立。-反对称性Antisymmetry如果a b且b a则必须保证a b。-传递性Transitivity如果a b且b c则必须保证a c。
延伸阅读

更多相关文章

2026/9/11 22:02:42

本地大模型Ollama实战:MES工程师的私有知识库搭建指南

一、问题背景:为什么FAB工艺工程师需要本地大模型作为FAB的工艺工程师,每天的工作几乎都离不开“查资料”这三个字。清晨到岗,先要看昨夜的异常批次处置记录;做工艺变更,要翻SOP确认参数窗口;设备报警&…

2026/9/9 3:05:21

半导体数字孪生实战:从FAB物理模型到虚拟镜像的全链路搭建

一、问题背景:百亿投资下的试产风险建设一座现代化的晶圆厂,动辄需要投入上百亿资金。厂房、洁净室、动力设施与成套的工艺设备构成了庞大的固定资产,而其中最昂贵、最精密的部分正是那些用于刻蚀、薄膜沉积与光刻的核心设备。当这些设备安装…

2026/9/12 18:40:58

学生选课系统数据库设计:从ER建模到SQL Server存储过程与索引优化

简介:面向高校数据库课程设计的一份完整参考资源,课题为某高校学生选课系统的设计,适合正在学习数据库原理、需要完成课程设计报告与数据库实现的学生。压缩包共3个文件,分别是课程设计报告doc、数据库脚本sql和数据库备份bak&…

2026/9/12 18:40:58

基于Neo4j的医疗知识图谱问答系统:从实体识别到Cypher查询

简介:基于Python的知识图谱医疗领域问答系统项目,面向Python学习者和知识图谱入门者,提供一套可完整运行的医疗领域问答系统源码与配套数据,适合作为期末大作业或课程设计参考。整个项目针对医疗知识结构化表示与自动问答实现进行…

2026/9/12 18:40:58

极简云验证商业版:轻量级SaaS身份核验与卡密管理方案

简介:本资源为已开源的极简云验证商业版完整源码包,面向PHP开发者、中小型SaaS服务搭建者及需要二次开发授权验证系统的技术人员,解决商用级账号注册、卡密解绑与查询等核心业务场景的快速落地问题。压缩包共1814个文件,以368个PH…

2026/9/12 18:40:58

微信小程序云开发校园应用工程实践:教务+生活+服务三域闭环

简介:本资源是一套基于微信小程序平台的TOGO智慧校园全功能源码,面向高校开发者、计算机专业学生及校园信息化项目实践者,旨在解决教务管理、生活服务与校园社交等多维场景的快速落地问题。压缩包共186个文件,总大小35.66MB&#…

2026/9/12 18:40:58

.NET Framework 4.8安装与配置全指南

1. .NET Framework 4.8概述 作为微软.NET技术栈的经典版本,.NET Framework 4.8自2019年发布以来已成为Windows平台应用开发的重要基石。这个最终版运行时环境在兼容性、性能和安全方面都达到了成熟阶段,特别适合维护传统WinForms、WPF和ASP.NET项目。不…

2026/9/12 18:35:58

第二日总结:高效能人士的结构化复盘方法

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/12 2:05:33

超人会飞不算本事:系统稳定依赖清晰规则与边界设计

开头先不绕弯子。“#斯坦李吐槽dc 所以超人是无缘无故会飞的嘛哈哈哈哈哈哈哈锤哥真是技术人才啊!#雷神 #复联”这类调侃式短标题,第一波冲击力在于它把两个宇宙的角色塞进同一个吐槽箱里,但细想一下就能发现,它真正碰到的根本不是…

2026/9/12 3:55:12

超人VS蜘蛛侠:拆解超级IP的影响力与传播方法论

把“蜘蛛侠 vs 超人”放在 CSDN 上聊,可能很多人第一反应是走错片场了。但如果把这两个角色看成“两个持续运营了 80 多年的文化产品”,你会发现,这场比较本质上是两个不同 IP 策略的长期结果对比:超人赢在定义了整个超级英雄题材…

2026/9/12 10:09:03

基于CNN的调制信号识别:MATLAB实现时频图分类实战

简介:本资源是一套面向通信工程与信号处理方向学习者、研究者的深度学习实践方案,聚焦调制信号自动检测与识别这一典型无线通信任务,解决传统方法依赖人工特征、低信噪比下性能下降等痛点。压缩包共12个文件(10.73MB)&…

2026/9/12 0:04:17

MATLAB仿生优化框架:长鼻浣熊算法多策略融合实现

简介:本资源是一份面向智能优化算法研究者与MATLAB初学者的仿生智能算法实践代码包,聚焦于长鼻浣熊优化算法(COA)的多策略改进与性能验证。针对传统COA易陷局部最优、收敛精度不足等问题,作者融合Circle映射初始化提升…

2026/9/12 0:04:17

【JAVA毕设源码分享】基于 JavaWeb 的校园一卡通管理系统的设计与实现 基于 JavaWeb 的校园卡业务管理系统(程序+文档+代码讲解+一条龙定制)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/9/12 0:04:17

【JAVA毕设源码分享】基于 Java 的图书馆借阅管理平台的搭建与实现 基于 Java 的图书馆综合管理系统(程序+文档+代码讲解+一条龙定制)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/9/12 6:29:36

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/12 14:32:17

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/12 6:37:43

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码