Comparisons

These traits support comparisons between values. All traits can be derived for types containing fields that implement these traits.

PartialEq and Eq

PartialEq is a partial equivalence relation, with required method eq and provided method ne. The == and != operators will call these methods.

  1. struct Key {
  2.     id: u32,
  3.     metadata: Option<String>,
  4. }
  5. impl PartialEq for Key {
  6.     fn eq(&self, other: &Self) -> bool {
  7.         self.id == other.id
  8.     }
  9. }

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 defines a partial ordering, with a partial_cmp method. It is used to implement the <, <=, >=, and > operators.

  1. use std::cmp::Ordering;
  2. #[derive(Eq, PartialEq)]
  3. struct Citation {
  4.     author: String,
  5.     year: u32,
  6. }
  7. impl PartialOrd for Citation {
  8.     fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
  9.         match self.author.partial_cmp(&other.author) {
  10.             Some(Ordering::Equal) => self.year.partial_cmp(&other.year),
  11.             author_ord => author_ord,
  12.         }
  13.     }
  14. }

Ord is a total ordering, with cmp returning Ordering.

This slide should take about 5 minutes.

PartialEq can be implemented between different types, but Eq cannot, because it is reflexive:

  1. struct Key {
  2.     id: u32,
  3.     metadata: Option<String>,
  4. }
  5. impl PartialEq<u32> for Key {
  6.     fn eq(&self, other: &u32) -> bool {
  7.         self.id == *other
  8.     }
  9. }

In practice, it’s common to derive these traits, but uncommon to implement them.