# 实践解析丨Rust 内置 trait：PartialEq 和 Eq

Rust 在很多地方使用了 traits, 从非常浅显的操作符重载, 到 Send, Sync 这种非常微妙的特性。一些 traits 是可以被自动派生的(你只需要写#[derive(Copy, Clone, PartialEq, Eq, Debug, Default, Hash, ...)] 就能得到一个神奇的实现, 它通常是对的。

PartialEq 和 Eq这两个 Traits 的名称实际上来自于抽象代数中的等价关系和局部等价关系，实际上两者的区别仅有一点，即是否在相等比较中是否满足反身性（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)
}
}``````

PartialEq 可使用 #[derive] 来交由编译器实现，当一个 struct 在进行相等比较时，会对其中每一个字段进行比较；如果遇到枚举时，还会对枚举所拥有的数据进行比较。

``````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")]
}``````

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

Eq 相比 PartialEq 需要额外满足反身性，即 a == a，对于浮点类型，Rust 只实现了 PartialEq 而不是 Eq，原因就是 NaN != NaN。

## Eq 和 Hash

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

1.1k 声望
1.6k 粉丝