溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

怎么使用Rust內(nèi)置trait:PartialEq和Eq

發(fā)布時(shí)間:2021-10-15 13:44:14 來(lái)源:億速云 閱讀:175 作者:iii 欄目:編程語(yǔ)言

本篇內(nèi)容主要講解“怎么使用Rust內(nèi)置trait:PartialEq和Eq”,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來(lái)帶大家學(xué)習(xí)“怎么使用Rust內(nèi)置trait:PartialEq和Eq”吧!

Rust 在很多地方使用了 traits, 從非常淺顯的操作符重載, 到 Send, Sync 這種非常微妙的特性。一些 traits 是可以被自動(dòng)派生的(你只需要寫(xiě)#[derive(Copy, Clone, PartialEq, Eq, Debug, Default, Hash, ...)] 就能得到一個(gè)神奇的實(shí)現(xiàn), 它通常是對(duì)的。

PartialEq 和 Eq這兩個(gè) Traits 的名稱(chēng)實(shí)際上來(lái)自于抽象代數(shù)中的等價(jià)關(guān)系和局部等價(jià)關(guān)系,實(shí)際上兩者的區(qū)別僅有一點(diǎn),即是否在相等比較中是否滿足反身性(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)
    }
}

如果我們想比較某個(gè)類(lèi)型的兩個(gè)值 x 和 y 是否相等(不等),例如:x == y (x != y),那么我們就必須為類(lèi)型實(shí)現(xiàn) PartialEq Trait。

PartialEq 可使用 #[derive] 來(lái)交由編譯器實(shí)現(xiàn),當(dāng)一個(gè) struct 在進(jìn)行相等比較時(shí),會(huì)對(duì)其中每一個(gè)字段進(jìn)行比較;如果遇到枚舉時(shí),還會(huì)對(duì)枚舉所擁有的數(shù)據(jù)進(jìn)行比較。

我們也可以自己實(shí)現(xiàn) PartialEq,實(shí)現(xiàn)時(shí)只需要實(shí)現(xiàn)判斷是否相等的函數(shù) fn eq(&self, other: &Self) -> bool ,Rust 會(huì)自動(dòng)提供 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) {}
}

實(shí)現(xiàn) Eq 的前提是已經(jīng)實(shí)現(xiàn)了 PartialEq,因?yàn)閷?shí)現(xiàn) Eq 不需要額外的代碼,只需要在實(shí)現(xiàn)了PartialEq 的基礎(chǔ)上告訴編譯器它的比較滿足自反性就可以了。對(duì)于上面的例子只需要:#[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

這兩個(gè) Traits 的名稱(chēng)實(shí)際上來(lái)自于抽象代數(shù)中的等價(jià)關(guān)系和局部等價(jià)關(guān)系。

等價(jià)關(guān)系(equivalence relation)即設(shè) \displaystyle RR 是某個(gè)集合 \displaystyle AA 上的一個(gè)二元關(guān)系。若 \displaystyle RR 滿足以下條件:

怎么使用Rust內(nèi)置trait:PartialEq和Eq

則稱(chēng) \displaystyle RR 是一個(gè)定義在 \displaystyle AA 上的等價(jià)關(guān)系。

并非所有的二元關(guān)系都是等價(jià)關(guān)系, Eq 和 PartialEq 的區(qū)別在于是否在相等比較中是否滿足自反性,即 x == x。

例如對(duì)于浮點(diǎn)類(lèi)型,Rust 只實(shí)現(xiàn)了 PartialEq 而沒(méi)有實(shí)現(xiàn) Eq,原因在于 NaN != Nan,不滿足自反性。

Eq 相比 PartialEq 需要額外滿足反身性,即 a == a,對(duì)于浮點(diǎn)類(lèi)型,Rust 只實(shí)現(xiàn)了 PartialEq 而不是 Eq,原因就是 NaN != NaN。

Eq 和 Hash

當(dāng)一個(gè)類(lèi)型同時(shí)實(shí)現(xiàn)了 Eq 和 Hash 時(shí),該類(lèi)型滿足下列特性:

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

即,當(dāng)兩個(gè) key 相等時(shí),它們的哈希值必然相等。Rust 里的 HashMap 和 HashSet 都依賴(lài)該特性。

到此,相信大家對(duì)“怎么使用Rust內(nèi)置trait:PartialEq和Eq”有了更深的了解,不妨來(lái)實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢(xún),關(guān)注我們,繼續(xù)學(xué)習(xí)!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI