當前位置: 首頁>>代碼示例 >>用法及示例精選 >>正文


Rust PartialEq用法及代碼示例


本文簡要介紹rust語言中 Trait std::cmp::PartialEq 的用法。

用法

pub trait PartialEq<Rhs = Self> where    Rhs: ?Sized, {
    fn eq(&self, other: &Rhs) -> bool;

    fn ne(&self, other: &Rhs) -> bool { ... }
}

相等比較的特征是 partial equivalence relations

x.eq(y) 也可以寫成 x == yx.ne(y) 可以寫成 x != y 。我們在本文檔的其餘部分使用easier-to-read 中綴表示法。

對於不具有完全等價關係的類型,此特征允許部分相等。例如,在浮點數 NaN != NaN 中,浮點類型實現了 PartialEq 而不是 Eq

實現必須確保eqne 彼此一致:

  • a != b 當且僅當 !(a == b)(由默認實現確保)。

如果 PartialOrd Ord 也為 SelfRhs 實現,它們的方法也必須與 PartialEq 一致(有關確切要求,請參閱這些特征的文檔)。通過派生一些特征並手動實現其他特征,很容易意外地使他們不同意。

等式關係==必須滿足以下條件(對於所有類型為ABCabc):

  • 對稱的: 如果A: PartialEq<B>B: PartialEq<A>, 然後a == b 意味著b == a;和

  • 傳遞的: 如果A: PartialEq<B>B: PartialEq<C>A: PartialEq<C>, 然後a == bb == c 意味著 a == c.

請注意,B: PartialEq<A>(對稱)和A: PartialEq<C>(傳遞)impls 不是強製存在的,但隻要它們確實存在,這些要求就適用。

可導出的

此特征可與 #[derive] 一起使用。當 derive d 在結構上時,如果所有字段相等,則兩個實例相等,如果任何字段不相等,則不相等。當 derive d 在枚舉上時,每個變體都等於自身,而不等於其他變體。

如何實現 PartialEq

一個域的示例實現,其中兩本書如果 ISBN 匹配則被視為同一本書,即使格式不同:

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
    }
}

let b1 = Book { isbn: 3, format: BookFormat::Paperback };
let b2 = Book { isbn: 3, format: BookFormat::Ebook };
let b3 = Book { isbn: 10, format: BookFormat::Paperback };

assert!(b1 == b2);
assert!(b1 != b3);

如何比較兩種不同的類型?

您可以比較的類型由 PartialEq 的類型參數控製。例如,讓我們稍微調整一下我們之前的代碼:

// The derive implements <BookFormat> == <BookFormat> comparisons
#[derive(PartialEq)]
enum BookFormat {
    Paperback,
    Hardback,
    Ebook,
}

struct Book {
    isbn: i32,
    format: BookFormat,
}

// Implement <Book> == <BookFormat> comparisons
impl PartialEq<BookFormat> for Book {
    fn eq(&self, other: &BookFormat) -> bool {
        self.format == *other
    }
}

// Implement <BookFormat> == <Book> comparisons
impl PartialEq<Book> for BookFormat {
    fn eq(&self, other: &Book) -> bool {
        *self == other.format
    }
}

let b1 = Book { isbn: 3, format: BookFormat::Paperback };

assert!(b1 == BookFormat::Paperback);
assert!(BookFormat::Ebook != b1);

通過將 impl PartialEq for Book 更改為 impl PartialEq<BookFormat> for Book ,我們允許將 BookFormat s 與 Book s 進行比較。

像上麵這樣忽略結構的某些字段的比較可能很危險。它很容易導致意外違反部分等價關係的要求。例如,如果我們為BookFormat 保留上述PartialEq<Book> 的實現,並為Book 添加PartialEq<Book> 的實現(通過#[derive] 或通過第一個示例中的手動實現),那麽結果將違反傳遞性:

#[derive(PartialEq)]
enum BookFormat {
    Paperback,
    Hardback,
    Ebook,
}

#[derive(PartialEq)]
struct Book {
    isbn: i32,
    format: BookFormat,
}

impl PartialEq<BookFormat> for Book {
    fn eq(&self, other: &BookFormat) -> bool {
        self.format == *other
    }
}

impl PartialEq<Book> for BookFormat {
    fn eq(&self, other: &Book) -> bool {
        *self == other.format
    }
}

fn main() {
    let b1 = Book { isbn: 1, format: BookFormat::Paperback };
    let b2 = Book { isbn: 2, format: BookFormat::Paperback };

    assert!(b1 == BookFormat::Paperback);
    assert!(BookFormat::Paperback == b2);

    // The following should hold by transitivity but doesn't.
    assert!(b1 == b2); // <-- PANICS
}

例子

let x: u32 = 0;
let y: u32 = 1;

assert_eq!(x == y, false);
assert_eq!(x.eq(&y), false);

相關用法


注:本文由純淨天空篩選整理自rust-lang.org大神的英文原創作品 Trait std::cmp::PartialEq。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。