これに似た質問を見たことがありますが、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,
}
これは基本的に同じものに拡張されます。