Rust比较:Ord和PartialOrd trait

1,371 阅读1分钟

Ord trait和PartialOrd trait

Ord trait用于对类型进行全序比较, 全序比较是指集合中的任两个元素之间都可以比较的关系。例如实数中的任两个数都可以比较大小,那么“大小”就是实数集的一个全序关系 ,它继承自PartialOrd trait和Eq trait。这意味着任何实现了Ord trait的类型都可以使用><>=<=等比较运算符。

与之相对应的是 PartialOrd trait,它用于对类型进行部分序比较。 部分序比较,也称为偏序比较,是指集合中的元素之间不一定都可以比较的关系。这种排序不必是全部的,就是说不需要保证此集合内的所有对象的相互可比较性 。这意味着对于某些值,它们之间可能无法进行比较。

Ord trait与PartialOrd trait的区别

与 PartialOrd trait不同, Ord trait要求类型之间的比较必须产生一个确定的结果。也就是说,对于任意两个值,它们必须是相等的、小于或大于。也是全序比较的意思。

Ord trait和PartialOrd trait的方法

Ord trait只有一个方法: cmp(self, other: &Self) -> Ordering. 它接受两个参数:self和other,并返回一个Ordering枚举值,表示self和other之间的关系。

use std::cmp::Ordering;

let x = 1;
let y = 2;

assert_eq!(x.cmp(&y), Ordering::Less);
assert_eq!(y.cmp(&x), Ordering::Greater);
assert_eq!(x.cmp(&x), Ordering::Equal);

与之相对应的是 PartialOrd trait中的 partial_cmp(self, other: &Self) -> Option<Ordering> 方法。它接受两个参数:self和other,并返回一个Option枚举值,表示self和other之间的关系。

let x: f64 = std::f64::NAN;
let y = 1.0f64;

// This will return None because NaN is not comparable to any float.
assert_eq!(x.partial_cmp(&y), None);

如何在自定义类型中实现 Ord trait和 PartialOrd trait

要在自定义类型中实现 Ord trait,需要先实现它的父trait: PartialOrdEq, 和 PartialEq.

use std::cmp::{Ordering, PartialEq, PartialOrd};

#[derive(Eq)]
struct Person {
    age: u32,
}

impl Ord for Person {
    fn cmp(&self, other: &Self) -> Ordering {
        self.age.cmp(&other.age)
    }
}

impl PartialOrd for Person {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

impl PartialEq for Person {
    fn eq(&self, other: &Self) -> bool {
        self.age == other.age
    }
}

let alice = Person { age: 30 };
let bob = Person { age: 25 };
let charlie = Person { age: 35 };

assert!(alice < charlie);
assert!(bob < alice);

上面是手动实现方法为其实现trait 也可以简洁一些,直接使用属性宏:

use std::cmp::{Ordering, PartialEq, PartialOrd}; 
 #[derive(Eq,PartialEq,Ord,PartialOrd)]
struct Person {
  age: u32,
 }
  let alice = Person { age: 30 };
  let bob = Person { age: 25 };
   let charlie = Person { age: 35 }; 
   assert!(alice < charlie);
   assert!(bob < alice);

这样代码简洁一些。总之,如果要想比较两个数据,可以使用Ord,和PratialOrd 。from刘金,转载请注明原文链接。感谢!