• Rust中partial设计用意和解决的问题
  • 发布于 2个月前
  • 291 热度
    0 评论
初学Rust时,在为自定义结构体实现PartialEq Trait时,误认为是用结构体中部分字段来参与相等比较计算,我想有可能也有其他初学者会和我犯同样的错误,这一篇是向初学者介绍Rust中partial设计用意和解决的问题。

在Rust中, trait处理了不是所有值都可以相互比较的情况。

PartialEq Trait
PartialEq trait用于定义值相等性的比较。它的设计允许类型的值之间进行相等(==)和不等(!=)的比较。与其对应的Eq trait确保一个类型的所有值都是可以可靠比较的,即满足等价关系的特性,如自反性、对称性和传递性。
fn eq(&self, other: &Self) -> bool;
fn ne(&self, other: &Self) -> bool;
在大多数情况下,类型的值都能够完全比较相等性,这时可以实现Eq。然而,对于一些特殊类型的值,如浮点数,由于存在无穷大的正负值和NaN值,导致它们的比较更加复杂。例如,根据IEEE浮点数的标准,NaN与任何值(包括它自己)比较都不相等。

PartialOrd Trait
PartialOrd trait用于定义值之间的大小比较。类似于PartialEq,它允许部分比较大小,返回一个Option,表示比较结果可能存在,也可能不存在(即比较无法进行时返回None)。
fn partial_cmp(&self, other: &Self) -> Option<Ordering>;
在全部比较可能的场景,我们会使用Ord trait,它要求实现cmp方法,总是返回一个Ordering,表示两个值之间的确切比较关系。Ord是在所有值都能够比较时使用的,例如整数和字符串。

设计用意和解决的问题
Rust设计PartialEq和PartialOrd trait主要出于以下几个理由:
非总序理念:并不是所有类型都有一个全局的排序方法。例如,复数之间就没有一个自然的大小顺序。为了避免为这些类型人为地赋予一个排序方法,Rust提供了一个只需部分实现序列操作的选择。
IEEE浮点数标准:由于浮点数标准定义了特殊值(NaN, 正负无穷),以及NaN不等于自身的规则,浮点数在一些情况下不能进行相等性或大小比较。
提升错误处理能力和安全性:通过返回Option<Ordering>,partial_cmp方法明确指出了比较可能失败的可能性,从而迫使程序员在使用时考虑并处理这种情况,增加了代码的正确性和稳健性。
表达性和灵活性:这些trait允许开发者为自定义类型定义适当的相等性和排序行为,从而加强了Rust类型系统的表达性和灵活性。
PartialEq和PartialOrd trait的设计允许程序员选择精准的相等性和排序语义,同时明确了对于某些类型相等性比较和大小排序并不总是可能的事实。通过引入适度的复杂性,让Rust的类型系统更加安全。
用户评论