Mehrere Implementierungsblöcke
Teil des Abschnitts Objektorientierte Programmierung der Rust-Journey von Coddy. Lektion 5 von 61.
Mit Rust kannst du die Methoden einer Struktur auf mehrere impl-Blöcke aufteilen. Obwohl alles in einen einzigen Block kommen könnte, kann ihre Trennung deinen Code übersichtlicher und besser lesbar machen.
Hier ist eine Struktur, deren Funktionalität auf zwei Implementierungsblöcke aufgeteilt ist:
struct BankAccount {
balance: f64,
}
// Konstruktor und grundlegende Abfragen
impl BankAccount {
fn new(initial: f64) -> BankAccount {
BankAccount { balance: initial }
}
fn balance(&self) -> f64 {
self.balance
}
}
// Transaktionsmethoden
impl BankAccount {
fn deposit(&mut self, amount: f64) {
self.balance += amount;
}
fn withdraw(&mut self, amount: f64) {
self.balance -= amount;
}
}
Beide Blöcke arbeiten nahtlos zusammen: Rust behandelt sie so, als wären sie einer. Du kannst jede Methode aufrufen, unabhängig davon, in welchem Block sie definiert ist:
fn main() {
let mut account = BankAccount::new(100.0);
account.deposit(50.0);
println!("{}", account.balance()); // 150
}
Dieses Muster wird besonders nützlich, wenn deine Strukturen wachsen. Du könntest Konstruktoren zusammenfassen, schreibgeschützte Methoden von verändernden Methoden trennen oder nach Funktionen organisieren. Es gibt keine Begrenzung dafür, wie viele impl-Blöcke eine Struktur haben kann.
Aufgabe
EinfachErstelle eine Player-Struktur mit zwei Feldern: name (String) und score (u32).
Organisiere die Methoden der Struktur über zwei separate Implementierungsblöcke:
Erster impl-Block: Konstruktor und Abfrage:
new: eine zugehörige Funktion, die einenname: Stringentgegennimmt und einenPlayerzurückgibt, bei demscoreauf0gesetzt istget_score: nimmt&selfentgegen und gibt den aktuellen Punktestand alsu32zurück
Zweiter impl-Block: Änderungen des Punktestands:
add_points: nimmt&mut selfundpoints: u32entgegen und addiert die Punkte zum Punktestandreset_score: nimmt&mut selfentgegen und setzt den Punktestand wieder auf0
Du erhältst drei Eingaben:
- Erste Zeile: der Name des Spielers (String)
- Zweite Zeile: die im ersten Durchgang hinzuzufügenden Punkte (u32)
- Dritte Zeile: die im zweiten Durchgang hinzuzufügenden Punkte (u32)
Erstelle einen Spieler mit Player::new, addiere die Punkte des ersten Durchgangs, gib den Punktestand aus, setze anschließend den Punktestand zurück, addiere die Punkte des zweiten Durchgangs und gib den endgültigen Punktestand aus.
Erwartetes Ausgabeformat:
{score_after_first_round}
{score_after_reset_and_second_round}Probier es selbst
use std::io;
// TODO: Definiere die Player-Struktur mit name (String) und score (u32) Feldern
// TODO: Erster impl-Block - Konstruktor- und Abfragemethoden (new, get_score)
// TODO: Zweiter impl-Block - Methoden zur Score-Modifikation (add_points, reset_score)
fn main() {
let mut input = String::new();
// Spielername lesen
io::stdin().read_line(&mut input).expect("Failed to read line");
let name = input.trim().to_string();
// Punkte der ersten Runde lesen
input.clear();
io::stdin().read_line(&mut input).expect("Failed to read line");
let first_round: u32 = input.trim().parse().expect("Invalid number");
// Punkte der zweiten Runde lesen
input.clear();
io::stdin().read_line(&mut input).expect("Failed to read line");
let second_round: u32 = input.trim().parse().expect("Invalid number");
// TODO: Erstelle einen Spieler mit Player::new
// TODO: Füge die Punkte der ersten Runde hinzu und gib den Score aus
// TODO: Setze den Score zurück
// TODO: Füge die Punkte der zweiten Runde hinzu und gib den finalen Score 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