構造体にOrdを実装するにはどうすればいいですか? 質問する

構造体に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_cmpeq関数を追加しましたが、両方のメソッドが のメンバーではないというエラーが発生しますOrd

ベストアンサー1

の定義Ordこれですか:

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

を実装する型は、 およびOrdも実装する必要があります。 に対してこれらの特性を実装する必要があります。EqPartialOrd<Self>SomeNum

ちなみに、実装が間違っているように見えます。self.value比較対象が だけである場合、ではなく でself.value > other.valueある必要があります。GreaterLess

必要に応じて、Ordの実装を使用して支援することができます。u32self.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,
}

これは基本的に同じものに拡張されます。

おすすめ記事