比较

这些 trait 支持在值之间进行比较。对于包含实现这些 trait 的字段,可以派生所有这些 trait。

PartialEq and Eq

PartialEq 指部分等价关系,其中包含必需的方法 eq 和提供的方法 ne==!= 运算符会调用这些方法。

struct Key {
    id: u32,
    metadata: Option<String>,
}
impl PartialEq for Key {
    fn eq(&self, other: &Self) -> bool {
        self.id == other.id
    }
}

Eq is a full equivalence relation (reflexive, symmetric, and transitive) and implies PartialEq. Functions that require full equivalence will use Eq as a trait bound.

PartialOrd and Ord

PartialOrd 定义了使用 partial_cmp 方法的部分排序。它用于实现 <<=>=> 运算符。

use std::cmp::Ordering;
#[derive(Eq, PartialEq)]
struct Citation {
    author: String,
    year: u32,
}
impl PartialOrd for Citation {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        match self.author.partial_cmp(&other.author) {
            Some(Ordering::Equal) => self.year.partial_cmp(&other.year),
            author_ord => author_ord,
        }
    }
}

Ord 是总排序,其中 cmp 返回 Ordering

This slide should take about 5 minutes.
  • PartialEq 可以在不同类型之间实现,但 Eq 不能,因为它具有自反性:

    struct Key {
        id: u32,
        metadata: Option<String>,
    }
    impl PartialEq<u32> for Key {
        fn eq(&self, other: &u32) -> bool {
            self.id == *other
        }
    }
  • 在实践中,派生这些 trait 很常见,但很少会实现它们。

  • When comparing references in Rust, it will compare the value of the things pointed to, it will NOT compare the references themselves. That means that references to two different things can compare as equal if the values pointed to are the same:

    fn main() {
        let a = "Hello";
        let b = String::from("Hello");
        assert_eq!(a, b);
    }