问题描述
我见过一个与此类似的问题,但没有人告诉我如何为结构体实现 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_cmp
和 eq
函数,但它给我的错误是这两种方法都不是 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
的类型也必须实现Eq
和PartialOrd
.您必须为 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?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!