Gleichheits-Traits
Teil des Abschnitts Objektorientierte Programmierung der Rust-Journey von Coddy. Lektion 38 von 61.
Das Vergleichen zweier Instanzen einer benutzerdefinierten Struktur mit == funktioniert in Rust standardmäßig nicht. Der Compiler weiß nicht, wie er bestimmen soll, ob zwei Strukturen gleich sind. Du musst es ihm mitteilen, indem du das PartialEq-Trait implementierst.
Wie Debug und Copy kannst du 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 PartialEq abgeleitet wird, vergleicht es jedes Feld der Struktur. Zwei Instanzen sind nur dann gleich, wenn alle entsprechenden Felder übereinstimmen.
Du wirst auch auf Eq stoßen. Dabei handelt es sich um ein Marker-Trait, das vollständige Gleichheit anzeigt, was bedeutet, dass jeder Wert sich selbst entspricht. Die meisten Typen erfüllen diese Bedingung, Gleitkommazahlen jedoch nicht (weil NaN != NaN). Bei Strukturen mit Ganzzahlfeldern kannst du sicher beide ableiten:
#[derive(PartialEq, Eq)]
struct Coordinate {
x: i32,
y: i32,
}
Eq hat keine eigenen Methoden. Es signalisiert lediglich, dass der Typ reflexive Gleichheit besitzt. Einige Funktionen der Standardbibliothek erfordern zusätzlich zu PartialEq auch Eq, daher ist es üblich, beide gemeinsam für geeignete Typen abzuleiten.
Aufgabe
EinfachLass uns ein Farbabgleichsystem erstellen, das zeigt, wie die Traits PartialEq und Eq den Vergleich zwischen Instanzen einer Struktur ermöglichen!
Du erstellst zwei Dateien, um deine Farbvergleichslogik zu organisieren:
color.rs: Definiere eine öffentlicheColor-Struktur mit drei öffentlichen Feldern:red,greenundblue(alleu8). Leite sowohlPartialEqals auchEqab, damit zwei Farben mit==verglichen werden können. Beim Ableiten betrachtet Rust zwei Farben nur dann als gleich, wenn alle drei RGB-Komponenten exakt übereinstimmen.main.rs: Binde dein Farbmodul ein und erstelle anhand der bereitgestellten Eingaben zweiColor-Instanzen. Vergleiche sie mit==und gib aus, ob sie übereinstimmen oder nicht.
Deine Ausgabe sollte angeben, ob die beiden Farben identisch sind:
Color 1: rgb({r1}, {g1}, {b1})
Color 2: rgb({r2}, {g2}, {b2})
Colors match: {true/false}Zum Beispiel bei den Eingaben 255, 128, 0, 255, 128, 0:
Color 1: rgb(255, 128, 0)
Color 2: rgb(255, 128, 0)
Colors match: trueUnd bei den Eingaben 100, 100, 100, 200, 200, 200:
Color 1: rgb(100, 100, 100)
Color 2: rgb(200, 200, 200)
Colors match: falseDu erhältst sechs Eingaben: die RGB-Werte für die erste Farbe (drei Werte), gefolgt von den RGB-Werten für die zweite Farbe (drei Werte). Wandle jeden Wert in u8 um.
Probier es selbst
mod color;
use color::Color;
fn main() {
// Lies die sechs RGB-Werte
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 mit den geparsten Werten
// TODO: Gib Color 1 im Format aus: Color 1: rgb(r, g, b)
// TODO: Gib Color 2 im Format aus: Color 2: rgb(r, g, b)
// TODO: Compare the two colors using == and print: Colors match: {true/false}
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1Methoden und Verhalten
Einführung in ImplementierungsblöckeDer Self-ParameterVeränderliche MethodenAssoziierte FunktionenMehrere ImplementierungsblöckeMethod ChainingRückblick – Rechteck-Aktionen4Projekt: Virtuelles Haustier
Das Haustier definierenDas Haustier füttern7Standard-Traits
Das Debug-TraitDas Display-TraitClone und CopyGleichheits-TraitsZusammenfassung – Druckbarer Punkt10Projekt: Dokumentensystem
Das Draw-TraitText-Komponente2Kapselung und Module
Grundlagen der ModuleDas Public-SchlüsselwortPrivate FelderGetterSetterWiederholung – Sicherer Tresor5Generics
Generische StructsGenerische MethodenMehrere generische TypenGenerische FunktionenZusammenfassung - Koordinatenpunkt8Traits als Einschränkungen
Syntax für Trait BoundsMehrfache BoundsDie Where-KlauselTypen mit Traits zurückgebenRückblick – Generischer Drucker11Design Patterns in Rust
Newtype-PatternKompositionDas Drop-TraitFrom und IntoZusammenfassung – Smart Pointer Mock3Fortgeschrittene Enums
Enums mit DatenMethoden für EnumsMatching von DatenvariantenDas Option-Enum erneut betrachtetZusammenfassung – Shape-Enum6Definition von Traits
Was ist ein Trait?Traits implementierenStandardimplementierungenStandardimplementierungen überschreibenTraits mit ParameternZusammenfassung – Media PlayerÜbe selbstständig: Online-Rust-Compiler