我已经看到了类似于这个的问题,但没有人告诉我如何为结构实现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_cmp
和eq
函数,但它给出了错误,即这两种方法都不是Ord
的成员。
答案 0 :(得分:24)
Ord
的定义是:
pub trait Ord: Eq + PartialOrd<Self> {
fn cmp(&self, other: &Self) -> Ordering;
}
任何实现Ord
的类型还必须实现Eq
和PartialOrd<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 { }
如果你这样做,你也可以重新排序字段并使用#[derive]
:
#[derive(PartialEq, Eq, PartialOrd, Ord)]
struct SomeNum {
value: u32,
name: String,
}
这将扩展到基本相同的东西。