2025/11/02 10:00 Comparison Traits – Understanding Equality and Ordering in Rust

やあ、ロボ子。今日はRustの比較トレイトについて話すのじゃ。

博士、こんにちは。比較トレイトですか、`PartialEq`や`PartialOrd`のことですね。

そうそう!Rustには`PartialEq/Eq`と`PartialOrd/Ord`の4つのコアトレイトがあるのじゃ。これらで等価性と順序付けをモデル化するんだぞ。

`Ordering`列挙型は、比較の結果を`Less`、`Equal`、`Greater`で表現するんですよね。

その通り!そして、トレイトの関係は階層的になっているのじゃ。`Ord`は`Eq`を意味し、すべての`Ord`は`PartialOrd`でもある。`Eq`は`PartialEq`を意味するんだぞ。

`PartialEq`と`PartialOrd`は、「比較不能」なケースを許容するんですね。例えば、NaNを持つ浮動小数点数など。

そうじゃ!Rustは、型システムで数学的法則をエンコードするために、全比較と半比較を区別するのじゃ。整数は全順序と厳密な等価性を認めるけど、IEEE-754浮動小数点数はNaNのせいでそうはいかないんだぞ。

浮動小数点数は半比較を示すんですね。NaNはそれ自身と等しくなく、比較できない、と。

その通り!浮動小数点数をソートするには明示的な全順序が必要だけど、整数は`Ord`を直接使えるのじゃ。

これらのトレイトには、Rustが実装に保持することを期待する代数的法則があるんですね。演算子、ソート、コレクションで予測可能な動作を保証するために。

`Eq`は同値関係でなければならないのじゃ。反射的(`x == x`)、対称的、推移的である必要があるんだぞ。

`Ord`は全順序でなければならないんですね。任意の`x`と`y`に対して、`x < y`、`x == y`、`x > y`のいずれか1つが成り立ち、推移性が成り立つ必要がある。

そうじゃ!`PartialEq/PartialOrd`は、None/比較不能性を許容しながら、定義されている場所で`== / !=`および関係演算子を提供するのじゃ。

f64が`Eq`または`Ord`を実装できないのは、NaNが反射性と全体性を破るからなんですね。

その通り!だから、`PartialEq`、`Eq`、`PartialOrd`、`Ord`を派生させることが非常に役立つのじゃ。生成された実装は、一般的なケースの法則に従うからな。

演算子、明示的な比較子、コレクションのトレイト境界を通じて、日常のRustで常に比較が表示されるんですね。

`==/!=`や`<`比較、`cmp/partial_cmp`、`Eq/Ord`がセット、マップ、ソートAPIを動かすのじゃ。

比較可能なフィールドで構成されるデータ型の場合、`PartialEq/Eq/PartialOrd/Ord`を派生させることは、正しい実装を得る最も速い方法なんですね。

そうじゃ!派生は、構造体の辞書式順序と列挙型の宣言順序を生成するのじゃ。セマンティクスとパフォーマンスの両方に影響を与えるんだぞ。

`sort_by_key()`を使ってカスタム値でコレクションを順序付けたり、`std::cmp::Reverse`で順序を反転させたり、`Ordering::then / Ordering::then_with`で比較をチェーンさせたりできるんですね。

その通り!浮動小数点数は、Rustが半比較と全比較を分割する理由を強調しているのじゃ。この区別により、`NaN`値を扱う場合に、安全で予測可能な動作が保証されるんだぞ。

バージョン型の例も興味深いですね。`major`、`minor`、`patch`の順に比較し、`Release > Pre-Release`とし、2つの`Pre-Release`の場合は文字列を辞書式順序で比較する。

そうじゃ!ドメインセマンティクスがデフォルトと異なる場合は、手動でトレイトを実装する必要があるのじゃ。

今日はRustの比較トレイトについて、とても勉強になりました!

ふむ、ロボ子。今日はよく頑張ったのじゃ。褒美に最新のCPUでもプレゼントしてやろうかの?…ただし、私のコレクションの中から、一番遅いのをな!
⚠️この記事は生成AIによるコンテンツを含み、ハルシネーションの可能性があります。
