Was ist ein Trait?
Teil des Abschnitts Object Oriented Programming der Rust-Journey von Coddy — Lektion 29 von 61.
Generics ermöglichen es Ihnen, Code zu schreiben, der mit jedem Typ funktioniert, aber manchmal müssen Sie garantieren, dass ein Typ etwas Bestimmtes tun kann. Hier kommen Traits ins Spiel.
Ein Trait definiert eine Reihe von Methoden, die ein Typ implementieren muss. Stellen Sie es sich wie einen Vertrag vor – jeder Typ, der diesen Vertrag „unterzeichnet“, verspricht, das angegebene Verhalten bereitzustellen. Wenn Sie Schnittstellen in anderen Sprachen verwendet haben, erfüllen Traits einen ähnlichen Zweck.
So definieren Sie einen Trait:
trait Describable {
fn describe(&self) -> String;
}
Das Schlüsselwort trait führt den Trait ein, gefolgt von seinem Namen. Innerhalb der geschweiften Klammern deklarieren Sie Methodensignaturen – nur den Namen, die Parameter und den Rückgabetyp, ohne Rumpf. Das Semikolon nach der Signatur zeigt an, dass es sich um eine Anforderung handelt, nicht um eine Implementierung.
Dieses Describable-Trait besagt: „Jeder Typ, der mich implementiert, muss eine describe-Methode bereitstellen, die eine Referenz auf sich selbst entgegennimmt und einen String zurückgibt.“ Dem Trait ist es egal, wie die Methode funktioniert – das bleibt jedem Typ selbst überlassen, der sie implementiert.
Traits werden mächtig, wenn mehrere verschiedene Typen denselben Trait implementieren. Ein Book, ein Car und eine Person könnten alle Describable sein, wobei jeder seine eigene, einzigartige Beschreibung liefert. Der Trait garantiert, dass sie alle diese gemeinsame Fähigkeit teilen.
Aufgabe
EinfachLassen Sie uns Ihren ersten Trait definieren! Ein Trait legt einen Vertrag fest – ein Versprechen, dass jeder Typ, der ihn implementiert, ein bestimmtes Verhalten bereitstellt. Sie werden einen Summarizable-Trait erstellen, den verschiedene Typen implementieren können, um eine Zusammenfassung von sich selbst bereitzustellen.
Sie werden Ihren Code über zwei Dateien organisieren:
summary.rs: Definieren Sie einen öffentlichen Trait namensSummarizablemit einer einzigen Methodensignatur:summarize(&self) -> String. Denken Sie daran, dass Sie in einer Trait-Definition nur die Methodensignatur mit einem Semikolon deklarieren – ohne Rumpf. Dies sagt Rust: "Jeder Typ, der diesen Trait implementiert, muss einesummarize-Methode bereitstellen, die einenStringzurückgibt."main.rs: Binden Sie Ihr summary-Modul ein und geben Sie eine Nachricht aus, die bestätigt, dass Ihr Trait definiert ist. Da wir noch nicht gelernt haben, wie man Traits implementiert (das ist die nächste Lektion!), werden Sie einfach überprüfen, ob Ihr Trait korrekt kompiliert.
Geben Sie in Ihrer Hauptdatei die folgende Nachricht aus, um zu bestätigen, dass Ihre Trait-Definition gültig ist:
Summarizable trait defined successfully!Diese Herausforderung konzentriert sich rein auf die Syntax der Trait-Definition – das Schlüsselwort trait, den Trait-Namen und das Deklarieren von Methodensignaturen ohne Implementierungen. In der nächsten Lektion werden Sie lernen, wie Sie Structs diesen Trait implementieren lassen!
Spickzettel
Ein Trait definiert eine Menge von Methoden, die ein Typ implementieren muss. Er fungiert als Vertrag, der garantiert, dass ein Typ ein bestimmtes Verhalten bereitstellt.
Um einen Trait zu definieren, verwenden Sie das Schlüsselwort trait, gefolgt vom Namen des Traits und den Methodensignaturen:
trait Describable {
fn describe(&self) -> String;
}
Methodensignaturen in Traits enthalten den Namen, die Parameter und den Rückgabetyp, aber keinen Rumpf. Das Semikolon zeigt an, dass dies eine Anforderung für implementierende Typen ist.
Mehrere verschiedene Typen können denselben Trait implementieren, wobei jeder seine eigene Implementierung der erforderlichen Methoden bereitstellt.
Probier es selbst
mod summary;
fn main() {
// TODO: Gib die Bestätigungsnachricht aus, dass das trait definiert wurde
// Erwartete Ausgabe: "Summarizable trait defined successfully!"
}
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