Menu
Coddy logo textTech

等価性のトレイト

CoddyのRustジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 38/61。

Rustでは、カスタムstructの2つのインスタンスを==で比較しても、デフォルトでは機能しません。コンパイラーは、2つのstructが等しいかどうかを判定する方法を知りません。PartialEq traitを実装して、それをコンパイラーに伝える必要があります。

DebugCopyと同様に、PartialEqも自動的にderiveできます。

#[derive(PartialEq)]
struct Coordinate {
    x: i32,
    y: i32,
}

let a = Coordinate { x: 5, y: 10 };
let b = Coordinate { x: 5, y: 10 };
let c = Coordinate { x: 3, y: 7 };

println!("{}", a == b);  // true
println!("{}", a == c);  // false

派生すると、PartialEqは構造体の各フィールドを比較します。対応するすべてのフィールドが一致する場合にのみ、2つのインスタンスは等しくなります。

Eqにも遭遇するでしょう。これは完全な等価性を示すマーカートレイトで、すべての値が自分自身と等しいことを意味します。ほとんどの型はこれを満たしますが、浮動小数点数は満たしません(NaN != NaNであるためです)。整数のfieldsを持つ構造体では、次の両方を安全にderiveできます。

#[derive(PartialEq, Eq)]
struct Coordinate {
    x: i32,
    y: i32,
}

Eq 自体にはメソッドがありません。これは、その型が反射律を満たす等価性を持つことを示すだけです。標準ライブラリの一部の機能では、PartialEq に加えて Eq も必要になるため、条件を満たす型では両方を一緒に derive するのが一般的です。

challenge icon

チャレンジ

簡単

PartialEqおよびEq traitsによって、struct instances間の比較が可能になる仕組みを示す、color matching systemを構築しましょう!

color comparison logicを整理するために、two filesを作成します。

  • color.rs: three public fields(redgreenblue、すべてu8)を持つpublic Color structをDefineします。PartialEqEqの両方をDeriveして、two colorsを== using比較できるようにします。導出すると、Rust will three RGB componentsがすべて完全に一致する場合にのみ、two colorsが等しいと見なします。
  • main.rs: color moduleを取り込み、提供されたinputsをusing two Color instancesをCreateします。== using比較し、一致するかどうかをPrintします。

outputには、two colorsが同じかどうかを示します。

Color 1: rgb({r1}, {g1}, {b1})
Color 2: rgb({r2}, {g2}, {b2})
Colors match: {true/false}

たとえば、inputsが25512802551280の場合:

Color 1: rgb(255, 128, 0)
Color 2: rgb(255, 128, 0)
Colors match: true

また、inputsが100100100200200200の場合:

Color 1: rgb(100, 100, 100)
Color 2: rgb(200, 200, 200)
Colors match: false

six inputsを受け取ります。最初のcolorのRGB values(three values)、続いてsecond colorのRGB values(three values)です。それぞれをu8としてParseします。

自分で試してみよう

mod color;

use color::Color;

fn main() {
    // 6つのRGB値を読み取る
    let mut input = String::new();
    std::io::stdin().read_line(&mut input).expect("Failed to read line");
    let r1: u8 = input.trim().parse().expect("Invalid input");

    input.clear();
    std::io::stdin().read_line(&mut input).expect("Failed to read line");
    let g1: u8 = input.trim().parse().expect("Invalid input");

    input.clear();
    std::io::stdin().read_line(&mut input).expect("Failed to read line");
    let b1: u8 = input.trim().parse().expect("Invalid input");

    input.clear();
    std::io::stdin().read_line(&mut input).expect("Failed to read line");
    let r2: u8 = input.trim().parse().expect("Invalid input");

    input.clear();
    std::io::stdin().read_line(&mut input).expect("Failed to read line");
    let g2: u8 = input.trim().parse().expect("Invalid input");

    input.clear();
    std::io::stdin().read_line(&mut input).expect("Failed to read line");
    let b2: u8 = input.trim().parse().expect("Invalid input");

    // TODO: 解析した値を使って2つのColorインスタンスを作成する

    // TODO: Color 1を次の形式で出力する: Color 1: rgb(r, g, b)

    // TODO: Color 2を次の形式で出力する: Color 2: rgb(r, g, b)

    // TODO: Compare the two colors using == and print: Colors match: {true/false}
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

オブジェクト指向プログラミングのすべてのレッスン

自分で練習してみよう: Rustオンラインコンパイラ