如何为结构实现Ord?

时间:2015-04-26 22:34:42

标签: rust ord

我已经看到了类似于这个的问题,但没有人告诉我如何为结构实现Ord。例如,以下内容:

struct SomeNum {
    name: String,
    value: u32,
}

impl Ord for SomeNum {
    fn cmp(&self, other:&Self) -> Ordering {
        let size1 = self.value;
        let size2 = other.value;
        if size1 > size2 {
            Ordering::Less
        }
        if size1 < size2 {
            Ordering::Greater
        }
        Ordering::Equal
    }
}

这给了我错误:

error: the trait `core::cmp::Eq` is not implemented for the type `SomeNum` [E0277]

我该如何解决这个问题?我已经尝试将实现更改为:

impl Ord for SomeNum where SomeNum: PartialOrd + PartialEq + Eq {...}

并添加了相应的partial_cmpeq函数,但它给出了错误,即这两种方法都不是Ord的成员。

1 个答案:

答案 0 :(得分:24)

Ord的定义是:

pub trait Ord: Eq + PartialOrd<Self> {
    fn cmp(&self, other: &Self) -> Ordering;
}

任何实现Ord的类型还必须实现EqPartialOrd<Self>。您必须为SomeNum实现这些特征。

顺便说一下,你的实现看起来像是错误的方式;如果您要比较self.valueself.value > other.value应为Greater,而不是Less

如果您愿意,可以使用Ord上的u32实施方式提供帮助:self.value.cmp(other.value)

您还应该考虑Ord订购。例如,如果您的PartialEq实施需要考虑name,那么您的Ord实施也必须考虑。为方便起见,使用元组可能会很好(表明比较中最重要的字段是value,但如果它们相同,则应考虑name,类似这样的事情:

struct SomeNum {
    name: String,
    value: u32,
}

impl Ord for SomeNum {
    fn cmp(&self, other: &Self) -> Ordering {
        (self.value, &self.name).cmp(&(other.value, &other.name))
    }
}

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

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

impl Eq for SomeNum { }

如果你这样做,你也可以重新排序字段并使用#[derive]

#[derive(PartialEq, Eq, PartialOrd, Ord)]
struct SomeNum {
    value: u32,
    name: String,
}

这将扩展到基本相同的东西。