GitHub: https://github.com/storagezhanghtml
Emai: debugzhang@163.comgit
華爲雲社區: https://bbs.huaweicloud.com/blogs/250275github
Eq and PartialEq are traits that allow you to define total and partial equality between values, respectively. Implementing them overloads the == and != operators.函數
/// [`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
。ui
PartialEq
可以使用 #[derive]
來交由編譯器實現,當一個 struct
在進行相等比較時,會對其中每個字段進行比較;若是遇到枚舉時,還會對枚舉所擁有的數據進行比較。this
咱們也能夠本身實現 PartialEq
,實現時只須要實現判斷是否相等的函數 fn eq(&self, other: &Self) -> bool
,Rust 會自動提供 fn ne(&self, other: &Self) -> bool
。例子以下:spa
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 } }
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 {}
。debug
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 {}
這兩個 Traits 的名稱實際上來自於抽象代數中的等價關係和局部等價關係。code
等價關係(equivalence relation)即設 \(\displaystyle R\) 是某個集合 \(\displaystyle A\) 上的一個二元關係。若 \(\displaystyle R\) 知足如下條件:component
則稱 \(\displaystyle R\) 是一個定義在 \(\displaystyle A\) 上的等價關係。
並不是全部的二元關係都是等價關係, Eq
和 PartialEq
的區別在因而否在相等比較中是否知足自反性,即 x == x
。
例如對於浮點類型,Rust 只實現了 PartialEq
而沒有實現 Eq
,緣由在於 NaN != Nan
,不知足自反性。
Eq
相比 PartialEq
須要額外知足自反性,即 a == a
,對於浮點類型,Rust 只實現了 PartialEq 而不是 Eq,緣由就是 NaN != NaN
。
當一個類型同時實現了 Eq
和 Hash
時,該類型知足下列特性:
k1 == k2 -> hash(k1) == hash(k2)
即,當兩個 key 相等時,它們的哈希值必然相等。Rust 裏的 HashMap
和 HashSet
都依賴該特性。