本文簡要介紹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 == y
, x.ne(y)
可以寫成 x != y
。我們在本文檔的其餘部分使用easier-to-read 中綴表示法。
對於不具有完全等價關係的類型,此特征允許部分相等。例如,在浮點數 NaN != NaN
中,浮點類型實現了 PartialEq
而不是 Eq
。
實現必須確保eq
和ne
彼此一致:
a != b
當且僅當!(a == b)
(由默認實現確保)。
如果 PartialOrd
或 Ord
也為 Self
和 Rhs
實現,它們的方法也必須與 PartialEq
一致(有關確切要求,請參閱這些特征的文檔)。通過派生一些特征並手動實現其他特征,很容易意外地使他們不同意。
等式關係==
必須滿足以下條件(對於所有類型為A
、B
、C
的a
、b
、c
):
-
對稱的: 如果
A: PartialEq<B>
和B: PartialEq<A>
, 然後a == b
意味著b == a
;和 -
傳遞的: 如果
A: PartialEq<B>
和B: PartialEq<C>
和A: PartialEq<C>
, 然後a == b
和b == 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 PartialOrd.partial_cmp用法及代碼示例
- Rust PartialOrd用法及代碼示例
- Rust PartialOrd.lt用法及代碼示例
- Rust PartialOrd.le用法及代碼示例
- Rust PartialOrd.ge用法及代碼示例
- Rust PartialOrd.gt用法及代碼示例
- Rust ParseFloatError用法及代碼示例
- Rust ParseIntError用法及代碼示例
- Rust PanicInfo.payload用法及代碼示例
- Rust Path.components用法及代碼示例
- Rust PathBuf.with_capacity用法及代碼示例
- Rust Path.is_symlink用法及代碼示例
- Rust Path.canonicalize用法及代碼示例
- Rust Path.is_relative用法及代碼示例
- Rust Path.file_stem用法及代碼示例
- Rust Path.to_string_lossy用法及代碼示例
- Rust Path.display用法及代碼示例
- Rust PathBuf.into_os_string用法及代碼示例
- Rust PanicInfo用法及代碼示例
- Rust PathBuf.pop用法及代碼示例
- Rust Path.ancestors用法及代碼示例
- Rust Path用法及代碼示例
- Rust Path.is_dir用法及代碼示例
- Rust Path.strip_prefix用法及代碼示例
- Rust PathBuf.set_file_name用法及代碼示例
注:本文由純淨天空篩選整理自rust-lang.org大神的英文原創作品 Trait std::cmp::PartialEq。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。