Trait std::cmp::PartialEq 1.0.0[−][src]
pub trait PartialEq<Rhs = Self> where
Rhs: ?Sized, {
fn eq(&self, other: &Rhs) -> bool;
fn ne(&self, other: &Rhs) -> bool { ... }
}
Expand description
相等比较的 trait 是 部分等价关系。
x.eq(y)
也可以写成 x == y
,x.ne(y)
,也可以写成 x != y
。
在本文档的其余部分中,我们使用了更易于阅读的中缀符号。
对于没有完全等价关系的类型,这个 trait 允许部分相等。
例如,在浮点数 NaN != NaN
中,因此浮点类型实现 PartialEq
,但不实现 Eq
。
实现必须确保 eq
和 ne
彼此一致:
a != b
当且仅当!(a == b)
(由默认实现确保)。
如果 Self
和 Rhs
也实现了 PartialOrd
或 Ord
,则它们的方法也必须与 PartialEq
一致 (具体要求请参见那些 traits 的文档)。
通过派生一些 traits 并手动实现其他一些行为,很容易使它们不以为然。
等式关系 ==
必须满足以下条件 (对于所有类型为 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>
(symmetric) 和 A: PartialEq<C>
(transitive) 强制不是强制存在的,但是这些要求只要存在就适用。
Derivable
该 trait 可以与 #[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);
Run如何比较两种不同的类型?
您可以比较的类型由 PartialEq
的类型参数控制。
例如,让我们对之前的代码进行一些调整:
// 衍生工具 <BookFormat> == <BookFormat> 比较
#[derive(PartialEq)]
enum BookFormat {
Paperback,
Hardback,
Ebook,
}
struct Book {
isbn: i32,
format: BookFormat,
}
// 实现 <Book> == <BookFormat> 比较
impl PartialEq<BookFormat> for Book {
fn eq(&self, other: &BookFormat) -> bool {
self.format == *other
}
}
// 实现 <BookFormat> == <Book> 比较
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);
Run通过将 impl PartialEq for Book
更改为 impl PartialEq<BookFormat> for Book
,我们可以将 BookFormat 和 Book 进行比较。
像上面这样的比较 (它忽略了结构体的某些字段) 可能很危险。这很容易导致意外违反部分对等关系的要求。
例如,如果我们保留了以上针对 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);
// 以下应该通过传递性来保持,但不是。
assert!(b1 == b2); // <-- PANICS
}
RunExamples
let x: u32 = 0;
let y: u32 = 1;
assert_eq!(x == y, false);
assert_eq!(x.eq(&y), false);
Run