Menu
Coddy logo textTech

Gleichheits-Traits

Teil des Abschnitts Object Oriented Programming der Rust-Journey von Coddy — Lektion 38 von 61.

Das Vergleichen zweier Instanzen eines benutzerdefinierten Structs mit == funktioniert in Rust standardmäßig nicht. Der Compiler weiß nicht, wie er feststellen soll, ob zwei Structs gleich sind – Sie müssen es ihm mitteilen, indem Sie das PartialEq-Trait implementieren.

Wie Debug und Copy kann man PartialEq automatisch ableiten:

#[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

Wenn es abgeleitet wird, vergleicht PartialEq jedes Feld des Structs. Zwei Instanzen sind nur dann gleich, wenn alle ihre entsprechenden Felder übereinstimmen.

Sie werden auch auf Eq stoßen, was ein Marker-Trait ist, der totale Gleichheit anzeigt – was bedeutet, dass jeder Wert sich selbst entspricht. Die meisten Typen erfüllen dies, aber Gleitkommazahlen nicht (da NaN != NaN). Für Structs mit Integer-Feldern können Sie sicher beides ableiten:

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

Eq besitzt keine eigenen Methoden – es signalisiert lediglich, dass der Typ reflexive Gleichheit besitzt. Einige Funktionen der Standardbibliothek erfordern Eq zusätzlich zu PartialEq, daher ist es üblich, beide zusammen für Typen abzuleiten, die dafür infrage kommen.

challenge icon

Aufgabe

Einfach

Lassen Sie uns ein Farbabgleichssystem erstellen, das zeigt, wie die Traits PartialEq und Eq den Vergleich zwischen Struct-Instanzen ermöglichen!

Sie werden zwei Dateien erstellen, um Ihre Farbabgleichslogik zu organisieren:

  • color.rs: Definieren Sie ein öffentliches Color-Struct mit drei öffentlichen Feldern: red, green und blue (alle u8). Leiten Sie sowohl PartialEq als auch Eq ab, damit zwei Farben mit == verglichen werden können. Wenn diese abgeleitet sind, betrachtet Rust zwei Farben nur dann als gleich, wenn alle drei RGB-Komponenten exakt übereinstimmen.
  • main.rs: Binden Sie Ihr Farbmodul ein und erstellen Sie zwei Color-Instanzen unter Verwendung der bereitgestellten Eingaben. Vergleichen Sie diese mit == und geben Sie aus, ob sie übereinstimmen oder nicht.

Ihre Ausgabe sollte angeben, ob die beiden Farben gleich sind:

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

Zum Beispiel mit den Eingaben 255, 128, 0, 255, 128, 0:

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

Und mit den Eingaben 100, 100, 100, 200, 200, 200:

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

Sie erhalten sechs Eingaben: die RGB-Werte für die erste Farbe (drei Werte), gefolgt von den RGB-Werten für die zweite Farbe (drei Werte). Parsen Sie jeden Wert als u8.

Spickzettel

Um benutzerdefinierte Structs mit == zu vergleichen, implementieren Sie das PartialEq-Trait, indem Sie es ableiten (deriven):

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

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

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

Wenn es abgeleitet wird, vergleicht PartialEq alle Felder – zwei Instanzen sind nur dann gleich, wenn alle entsprechenden Felder übereinstimmen.

Das Eq-Trait ist ein Marker-Trait, das totale Gleichheit anzeigt (jeder Wert ist gleich sich selbst). Die meisten Typen erfüllen dies, außer Gleitkommazahlen (da NaN != NaN). Für Structs mit Integer-Feldern leiten Sie beide Traits zusammen ab:

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

Eq hat keine Methoden – es signalisiert reflexive Gleichheit. Einige Funktionen der Standardbibliothek erfordern Eq zusätzlich zu PartialEq.

Probier es selbst

mod color;

use color::Color;

fn main() {
    // Lies die sechs RGB-Werte ein
    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: Erstelle zwei Color-Instanzen unter Verwendung der parsierten Werte

    // TODO: Gib Color 1 im Format: Color 1: rgb(r, g, b) aus

    // TODO: Gib Color 2 im Format: Color 2: rgb(r, g, b) aus

    // TODO: Vergleiche die beiden Farben mit == und gib aus: Colors match: {true/false}
}
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Object Oriented Programming