Как мне реализовать 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_cmp
а также eq
функции, но это дает мне ошибку, что оба эти метода не являются членами Ord
,
1 ответ
Определение 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,
}
Это расширится в основном до того же самого.