如何为结构实现Ord?

Dum*_*les 17 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
    }
}
Run Code Online (Sandbox Code Playgroud)

这给了我错误:

error: the trait `core::cmp::Eq` is not implemented for the type `SomeNum` [E0277]
Run Code Online (Sandbox Code Playgroud)

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

impl Ord for SomeNum where SomeNum: PartialOrd + PartialEq + Eq {...}
Run Code Online (Sandbox Code Playgroud)

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

Chr*_*gan 25

定义Ord是这样的:

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

任何实现的类型也Ord必须实现EqPartialOrd<Self>.你必须实现这些特征SomeNum.

顺便说一句,你的实现看起来像是错误的方式; 如果self.value你要比较,self.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 { }
Run Code Online (Sandbox Code Playgroud)

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

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

这将扩展到基本相同的事情.

  • 哦,是的,你想要的是`if size1 &lt; size2 { Ordering::Less } else if size1 &gt; size2 { Ordering::Greater } else { Ordering::Equal }`。`if` 表达式有一个类型,你实际上连续三个语句,其中前两个的值没有被使用,并且它们的类型也不一致,因为它们有一个隐式的 `else { }`是类型`()`。 (2认同)