Das Display-Trait
Teil des Abschnitts Objektorientierte Programmierung 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 benutzerseitige Ausgabe gedacht. Es ist die Grundlage für den {}-Formatierer in println!. Anders als Debug kann Rust Display nicht automatisch ableiten. Du musst es manuell implementieren.
Um Display zu implementieren, musst du das Modul fmt einbinden und die Methode fmt 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 empfängt einen Formatter und gibt ein fmt::Result zurück. Du verwendest das write!-Makro, um deine Ausgabe zu formatieren, und greifst über self auf die Felder der Struktur zu.
Jetzt kannst du die Struktur mit dem standardmäßigen {}-Formatierer ausgeben:
let temp = Temperature { celsius: 23.5 };
println!("{}", temp); // 23.5°C
Der entscheidende Unterschied: Die Debug-Ausgabe zeigt die Struktur deiner Daten (nützlich zum Debuggen), während die Display-Ausgabe aufbereitet ist und sich an Endbenutzer richtet. Eine Struktur kann beides implementieren: Verwende {:?} zum Debuggen und {} für eine übersichtliche Ausgabe.
Aufgabe
EinfachErstellen wir ein benutzerfreundliches Produktanzeigesystem! Während Debug die Rohstruktur deiner Daten anzeigt, ermöglicht dir das Merkmal Display, eine ansprechende, menschenlesbare Ausgabe zu erstellen, die perfekt für Endbenutzer geeignet ist.
Du organisierst deinen Code über zwei Dateien:
product.rs: Definiere eine öffentlicheProduct-Struktur mit zwei öffentlichen Feldern:name(String) undprice(f64). Implementiere das MerkmalDisplayfür deine Struktur, sodass sie als{name} - ${price}formatiert wird. Denke daran,std::fmteinzubinden und das Makrowrite!innerhalb deinerfmt-Methode zu verwenden.main.rs: Binde dein Produktmodul ein und erstelle eineProduct-Instanz mit den bereitgestellten Eingaben. Gib das Produkt mit dem standardmäßigen{}-Formatierer aus, um deine benutzerdefinierte Anzeigeausgabe zu zeigen.
Das Merkmal Display erfordert, dass du die fmt-Methode manuell implementierst: Rust kann sie nicht automatisch wie Debug ableiten. Dadurch erhältst du vollständige Kontrolle darüber, wie dein Typ für Benutzer angezeigt wird.
Deine Ausgabe sollte das Produkt in einem übersichtlichen, benutzerfreundlichen Format anzeigen:
{name} - ${price}Zum Beispiel mit den Eingaben Wireless Mouse und 29.99:
Wireless Mouse - $29.99Du erhältst zwei Eingaben: den Produktnamen und den Preis (als f64 parsen).
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: Erstelle eine Product-Instanz mit dem Namen und dem Preis
// TODO: Gib das Produkt mit dem {}-Formatter aus
}
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