如何为结构实现 Ord? [英] How do I implement Ord for a struct?

查看:37
本文介绍了如何为结构实现 Ord?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我见过一个与此类似的问题,但没有人告诉我如何为结构体实现 Ord.例如,以下内容:

I've seen a question similar to this one, but no one that tells me exactly how to implement Ord for a struct. For example, the following:

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]

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

How would I fix this? I have tried changing the implementation to:

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

并添加适当的 partial_cmpeq 函数,但它给我的错误是这两种方法都不是 Ord 的成员.

and adding the appropriate partial_cmp and eq functions but it gives me the error that both those methods are not a member of Ord.

推荐答案

Ord 是这样的:

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

任何实现Ord 的类型也必须实现EqPartialOrd.您必须为 SomeNum 实现这些特征.

Any type that implements Ord must also implement Eq and PartialOrd<Self>. You must implement these traits for SomeNum.

顺便说一句,您的实现方式似乎是错误的;如果 self.value 是您要比较的全部内容,则 self.value >other.value 应该是 Greater,而不是 Less.

Incidentally, your implementation looks like being the wrong way round; if self.value is all you are comparing, self.value > other.value should be Greater, not Less.

如果需要,您可以使用 u32 上的 Ord 实现来提供帮助:self.value.cmp(other.value).

You can use the Ord implementation on u32 to assist, should you desire it: self.value.cmp(other.value).

您还应该考虑到 Ord 是一个 total 排序.例如,如果您的 PartialEq 实现考虑了 name,那么您的 Ord 实现也必须考虑在内.为方便起见,最好使用元组(表示比较中最重要的字段是value,但如果它们相同,则应考虑name帐户),类似这样:

You should also take into account that Ord is a total ordering. If your PartialEq implementation, for example, takes name into consideration, your Ord implementation must also. It might be well to use a tuple for convenience (indicating that the most important field in the comparison is value, but that if they are the same, name should be taken into account), something like this:

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]:

If you’re doing it like this, you might as well reorder the fields and use #[derive]:

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

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

This will expand to basically the same thing.

这篇关于如何为结构实现 Ord?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆