Menu
Coddy logo textTech

Mehrere Implementierungsblöcke

Teil des Abschnitts Object Oriented Programming der Rust-Journey von Coddy — Lektion 5 von 61.

Rust erlaubt es Ihnen, die Methoden eines Structs auf mehrere impl-Blöcke aufzuteilen. Während alles in einem einzigen Block stehen könnte, kann die Aufteilung Ihren Code organisierter und lesbarer machen.

Hier ist ein Struct, dessen Funktionalität in 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. Sie können 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 Ihre Structs wachsen. Sie könnten Konstruktoren gruppieren, schreibgeschützte Methoden von verändernden trennen oder nach Funktionen organisieren. Es gibt keine Begrenzung dafür, wie viele impl-Blöcke ein Struct haben kann.

challenge icon

Aufgabe

Einfach

Erstellen Sie eine Player-Struktur mit zwei Feldern: name (String) und score (u32).

Organisieren Sie die Methoden der Struktur in zwei separaten Implementierungsblöcken:

Erster impl-Block — Konstruktor und Abfrage:

  • new — eine assoziierte Funktion, die einen name: String entgegennimmt und einen Player zurückgibt, dessen score auf 0 gesetzt ist
  • get_score — nimmt &self entgegen und gibt den aktuellen Punktestand als u32 zurück

Zweiter impl-Block — Punktmodifikationen:

  • add_points — nimmt &mut self und points: u32 entgegen und addiert die Punkte zum Punktestand
  • reset_score — nimmt &mut self entgegen und setzt den Punktestand zurück auf 0

Sie erhalten drei Eingaben:

  • Erste Zeile: der Name des Spielers (String)
  • Zweite Zeile: Punkte, die in der ersten Runde hinzugefügt werden sollen (u32)
  • Dritte Zeile: Punkte, die in der zweiten Runde hinzugefügt werden sollen (u32)

Erstellen Sie einen Spieler mit Player::new, fügen Sie die Punkte der ersten Runde hinzu, geben Sie den Punktestand aus, setzen Sie dann den Punktestand zurück, fügen Sie die Punkte der zweiten Runde hinzu und geben Sie den endgültigen Punktestand aus.

Erwartetes Ausgabeformat:

{score_after_first_round}
{score_after_reset_and_second_round}

Spickzettel

Rust ermöglicht es, die Methoden eines Structs auf mehrere impl-Blöcke aufzuteilen, um eine bessere Organisation zu erreichen:

struct BankAccount {
    balance: f64,
}

// First impl block
impl BankAccount {
    fn new(initial: f64) -> BankAccount {
        BankAccount { balance: initial }
    }
    
    fn balance(&self) -> f64 {
        self.balance
    }
}

// Second impl block
impl BankAccount {
    fn deposit(&mut self, amount: f64) {
        self.balance += amount;
    }
    
    fn withdraw(&mut self, amount: f64) {
        self.balance -= amount;
    }
}

Alle Methoden aus verschiedenen impl-Blöcken arbeiten nahtlos zusammen:

let mut account = BankAccount::new(100.0);
account.deposit(50.0);
println!("{}", account.balance()); // 150

Es gibt keine Begrenzung dafür, wie viele impl-Blöcke ein Struct haben kann. Dieses Muster ist nützlich, um zusammengehörige Funktionalitäten zu gruppieren, wie zum Beispiel die Trennung von Konstruktoren und verändernden Methoden.

Probier es selbst

use std::io;

// TODO: Definiere das Player-Struct mit den Feldern name (String) und score (u32)


// TODO: Erster impl-Block - Konstruktor und Abfragemethoden (new, get_score)


// TODO: Zweiter impl-Block - Methoden zur Score-Änderung (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: Punkte der ersten Runde hinzufügen und den Score ausgeben
    // TODO: Score zurücksetzen
    // TODO: Punkte der zweiten Runde hinzufügen und den finalen Score ausgeben
}
quiz iconTeste dich selbst

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