Veränderliche Methoden
Teil des Abschnitts Object Oriented Programming der Rust-Journey von Coddy — Lektion 3 von 61.
Manchmal müssen Methoden mehr tun, als nur Daten zu lesen – sie müssen sie ändern. Um Methoden zu erstellen, die die Felder eines Structs ändern können, verwenden wir &mut self anstelle von &self.
Das Schlüsselwort mut kennzeichnet eine veränderliche Ausleihe (mutable borrow) und gibt der Methode die Erlaubnis, den internen Zustand der Instanz zu ändern:
struct Counter {
value: i32,
}
impl Counter {
fn increment(&mut self) {
self.value += 1;
}
fn decrement(&mut self) {
self.value -= 1;
}
fn get(&self) -> i32 {
self.value
}
}
Beachten Sie, dass increment und decrement &mut self verwenden, da sie value ändern, während get &self verwendet, da es die Daten nur liest.
Beim Aufrufen von veränderlichen Methoden muss die Instanz selbst als veränderlich deklariert werden:
fn main() {
let mut counter = Counter { value: 0 };
counter.increment();
counter.increment();
println!("{}", counter.get()); // 2
counter.decrement();
println!("{}", counter.get()); // 1
}
Wenn Sie das Schlüsselwort mut beim Erstellen der Instanz vergessen, wird Rust Sie daran hindern, &mut self-Methoden darauf aufzurufen. Dies stellt sicher, dass Sie sich immer bewusst sind, wenn sich Ihre Daten ändern könnten.
Aufgabe
EinfachErstellen Sie ein BankAccount-Struct mit einem einzigen Feld: balance (i32).
Fügen Sie einen Implementierungsblock für BankAccount mit drei Methoden hinzu:
deposit— nimmt&mut selfund einenamount: i32entgegen und addiert den Betrag zum Kontostandwithdraw— nimmt&mut selfund einenamount: i32entgegen und subtrahiert den Betrag vom Kontostandget_balance— nimmt&selfentgegen und gibt den aktuellen Kontostand alsi32zurück
Sie erhalten drei Eingaben:
- Erste Zeile: der Anfangskontostand (i32)
- Zweite Zeile: der Einzahlungsbetrag (i32)
- Dritte Zeile: der Auszahlungsbetrag (i32)
Erstellen Sie eine veränderbare BankAccount-Instanz mit dem Anfangskontostand, zahlen Sie dann den angegebenen Betrag ein, heben Sie den angegebenen Betrag ab und geben Sie den endgültigen Kontostand aus.
Erwartetes Ausgabeformat:
{final_balance}Spickzettel
Methoden, die Struct-Felder ändern, verwenden &mut self (veränderbare Ausleihe), während Methoden, die Daten nur lesen, &self verwenden:
struct Counter {
value: i32,
}
impl Counter {
fn increment(&mut self) {
self.value += 1;
}
fn decrement(&mut self) {
self.value -= 1;
}
fn get(&self) -> i32 {
self.value
}
}
Um veränderbare Methoden aufzurufen, muss die Instanz mit let mut als veränderbar deklariert werden:
let mut counter = Counter { value: 0 };
counter.increment();
counter.increment();
println!("{}", counter.get()); // 2
counter.decrement();
println!("{}", counter.get()); // 1
Ohne das Schlüsselwort mut bei der Instanz verhindert Rust den Aufruf jeglicher &mut self-Methoden.
Probier es selbst
use std::io;
// TODO: Definiere hier das BankAccount-Struct
// TODO: Füge den Implementierungsblock für BankAccount mit den Methoden deposit, withdraw und get_balance hinzu
fn main() {
let mut input = String::new();
// Anfangssaldo lesen
io::stdin().read_line(&mut input).expect("Failed to read line");
let initial_balance: i32 = input.trim().parse().expect("Invalid number");
input.clear();
// Einzahlungsbetrag lesen
io::stdin().read_line(&mut input).expect("Failed to read line");
let deposit_amount: i32 = input.trim().parse().expect("Invalid number");
input.clear();
// Auszahlungsbetrag lesen
io::stdin().read_line(&mut input).expect("Failed to read line");
let withdraw_amount: i32 = input.trim().parse().expect("Invalid number");
// TODO: Erstelle eine veränderbare BankAccount-Instanz mit initial_balance
// TODO: Rufe deposit mit deposit_amount auf
// TODO: Rufe withdraw mit withdraw_amount auf
// TODO: Gib den Endsaldo mit get_balance 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