Das Display-Trait
Teil des Abschnitts Object Oriented Programming der Rust-Journey von Coddy — Lektion 36 von 61.
Während Debug großartig für Entwickler ist, die Daten untersuchen, ist das Display-Trait für die benutzerorientierte Ausgabe konzipiert. Es ist das, was den {}-Formatierer in println! antreibt. Im Gegensatz zu Debug kann Rust Display nicht automatisch ableiten – du musst es manuell implementieren.
Um Display zu implementieren, müssen Sie das fmt-Modul einbinden und die fmt-Methode implementieren:
use std::fmt;
struct Temperature {
celsius: f64,
}
impl fmt::Display for Temperature {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}°C", self.celsius)
}
}
Die fmt-Methode erhält einen Formatter und gibt ein fmt::Result zurück. Du verwendest das write!-Makro, um deine Ausgabe zu formatieren, wobei du auf die Felder des Structs über self zugreifst.
Jetzt können Sie das Struct mit dem Standard-{}-Formatierer ausgeben:
let temp = Temperature { celsius: 23.5 };
println!("{}", temp); // 23.5°C
Der entscheidende Unterschied: Die Debug-Ausgabe zeigt die Struktur Ihrer Daten (nützlich für das Debugging), während die Display-Ausgabe aufpoliert und für Endbenutzer gedacht ist. Ein Struct kann beides implementieren – verwenden Sie {:?} für das Debugging und {} für eine saubere Ausgabe.
Aufgabe
EinfachLassen Sie uns ein benutzerfreundliches Produktanzeigesystem erstellen! Während Debug die rohe Struktur Ihrer Daten zeigt, ermöglicht es das Display-Trait, eine polierte, menschenlesbare Ausgabe zu gestalten, die perfekt für Endbenutzer geeignet ist.
Sie werden Ihren Code über zwei Dateien organisieren:
product.rs: Definieren Sie eine öffentlicheProduct-Struktur mit zwei öffentlichen Feldern:name(String) undprice(f64). Implementieren Sie dasDisplay-Trait für Ihre Struktur, sodass sie als{name} - ${price}formatiert wird. Denken Sie daran,std::fmteinzubinden und daswrite!-Makro innerhalb Ihrerfmt-Methode zu verwenden.main.rs: Binden Sie Ihr Produktmodul ein und erstellen Sie eineProduct-Instanz unter Verwendung der bereitgestellten Eingaben. Geben Sie das Produkt mit dem Standard-{}-Formatierer aus, um Ihre benutzerdefinierte Anzeigeausgabe zu zeigen.
Das Display-Trait erfordert, dass Sie die fmt-Methode manuell implementieren – Rust kann dies nicht automatisch ableiten wie bei Debug. Dies gibt Ihnen die vollständige Kontrolle darüber, wie Ihr Typ für Benutzer erscheint.
Ihre Ausgabe sollte das Produkt in einem sauberen, benutzerfreundlichen Format anzeigen:
{name} - ${price}Zum Beispiel mit den Eingaben Wireless Mouse und 29.99:
Wireless Mouse - $29.99Sie erhalten zwei Eingaben: den Produktnamen und den Preis (parsen als f64).
Spickzettel
Der Display-Trait ist für die benutzerorientierte Ausgabe konzipiert und steuert den {}-Formatierer in println!. Im Gegensatz zu Debug muss er manuell implementiert werden.
Um Display zu implementieren, binden Sie das fmt-Modul ein und implementieren Sie die fmt-Methode:
use std::fmt;
struct Temperature {
celsius: f64,
}
impl fmt::Display for Temperature {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}°C", self.celsius)
}
}
Die fmt-Methode erhält einen Formatter und gibt ein fmt::Result zurück. Verwenden Sie das write!-Makro, um die Ausgabe zu formatieren, und greifen Sie über self auf die Struct-Felder zu.
Geben Sie das Struct mit dem {}-Formatierer aus:
let temp = Temperature { celsius: 23.5 };
println!("{}", temp); // 23.5°C
Wesentlicher Unterschied: Debug ({:?}) zeigt die Datenstruktur für das Debugging, während Display ({}) eine aufbereitete Ausgabe für Endbenutzer liefert.
Probier es selbst
mod product;
use product::Product;
fn main() {
let mut name = String::new();
std::io::stdin().read_line(&mut name).expect("Failed to read line");
let name = name.trim().to_string();
let mut price_input = String::new();
std::io::stdin().read_line(&mut price_input).expect("Failed to read line");
let price: f64 = price_input.trim().parse().expect("Failed to parse price");
// TODO: Erstellen Sie eine Product-Instanz mit dem Namen und dem Preis
// TODO: Geben Sie das Produkt mit dem {}-Formatierer aus
}
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
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