Menu
Coddy logo textTech

Setter

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

Getter ermöglichen es externem Code, private Daten zu lesen. Aber was ist, wenn Sie zulassen müssen, dass dieser sie ändert? Hier kommen Setter-Methoden ins Spiel – öffentliche Methoden, die private Felder auf kontrollierte Weise ändern.

Ein einfacher Setter nimmt &mut self und einen neuen Wert entgegen:

// wallet.rs
pub struct Wallet {
    balance: f64,
}

impl Wallet {
    pub fn new(initial: f64) -> Wallet {
        Self { balance: initial }
    }
    
    pub fn balance(&self) -> f64 {
        self.balance
    }
    
    pub fn set_balance(&mut self, amount: f64) {
        self.balance = amount;
    }
}

Im Gegensatz zu Gettern verwenden Rust-Setter normalerweise das Präfix set_, um deutlich anzuzeigen, dass sie Daten ändern. Der Parameter &mut self ist essenziell – er erteilt der Methode die Erlaubnis, die Felder des Structs zu ändern.

Die wahre Stärke von Settern ist die Validierung. Anstatt blind jeden Wert zu akzeptieren, können Sie Regeln erzwingen:

pub fn set_balance(&mut self, amount: f64) {
    if amount >= 0.0 {
        self.balance = amount;
    }
    // Negative Werte werden stillschweigend ignoriert
}

Jetzt schützt sich das Wallet selbst – egal welchen Wert externer Code zu setzen versucht, der Kontostand kann niemals negativ werden. Das ist Kapselung in Aktion: Das Struct kontrolliert seine eigenen Invarianten, und externer Code kann es schlichtweg nicht in einen ungültigen Zustand versetzen.

challenge icon

Aufgabe

Einfach

Lassen Sie uns ein Thermostatsystem bauen, das zeigt, wie Setter Regeln erzwingen können, um Daten valide zu halten. Ihr Thermostat wird eine Temperatureinstellung haben, die nur innerhalb eines sicheren Bereichs angepasst werden kann.

Sie werden zwei Dateien erstellen, um Ihren Code zu organisieren:

  • thermostat.rs: Definieren Sie ein Thermostat Struct mit einem privaten temperature Feld (i32). Das Struct sollte öffentlich sein, aber das Feld bleibt privat, um es vor ungültigen Werten zu schützen. Implementieren Sie:
    • Einen new Konstruktor, der eine Anfangstemperatur entgegennimmt
    • Einen temperature Getter, der die aktuelle Temperatur zurückgibt
    • Einen set_temperature Setter, der nur Werte zwischen 10 und 30 (einschließlich) akzeptiert. Wenn der Wert außerhalb dieses Bereichs liegt, sollte die Temperatur unverändert bleiben.
  • main.rs: Binden Sie Ihr Thermostat-Modul ein, erstellen Sie einen Thermostat und demonstrieren Sie die Validierung des Setters, indem Sie versuchen, verschiedene Temperaturen einzustellen und das Ergebnis nach jedem Versuch ausgeben.

Der Setter sollte ungültige Werte stillschweigend ignorieren – keine Fehlermeldungen, behalten Sie einfach die aktuelle Temperatur unverändert bei, wenn jemand versucht, sie außerhalb des gültigen Bereichs einzustellen.

Ihre Ausgabe sollte genau diesem Format folgen:

Initial: {temperature}
After setting to {attempted_value}: {temperature}
After setting to {attempted_value}: {temperature}

Wenn Sie zum Beispiel einen Thermostat bei 20 erstellen und dann versuchen, ihn auf 25 (gültig) und dann auf 50 (ungültig) einzustellen, wäre die Ausgabe:

Initial: 20
After setting to 25: 25
After setting to 50: 25

Sie erhalten drei Eingaben: die Anfangstemperatur, die erste zu versuchende Temperatur und die zweite zu versuchende Temperatur.

Spickzettel

Setter-Methoden ermöglichen es externem Code, private Felder auf kontrollierte Weise zu ändern. Sie nehmen &mut self entgegen, um die Erlaubnis zu erhalten, die Daten des Structs zu ändern.

Grundlegende Setter-Syntax:

pub fn set_balance(&mut self, amount: f64) {
    self.balance = amount;
}

Rust-Setter verwenden normalerweise das Präfix set_, um deutlich anzuzeigen, dass sie Daten ändern.

Setter ermöglichen eine Validierung, um Regeln durchzusetzen und die Datenintegrität zu wahren:

pub fn set_balance(&mut self, amount: f64) {
    if amount >= 0.0 {
        self.balance = amount;
    }
    // Ungültige Werte werden stillschweigend ignoriert
}

Dies ist Kapselung in Aktion: Das Struct kontrolliert seine eigenen Invarianten und verhindert, dass externer Code es in einen ungültigen Zustand versetzt.

Probier es selbst

mod thermostat;

use thermostat::Thermostat;

fn main() {
    // Eingaben lesen
    let mut input1 = String::new();
    std::io::stdin().read_line(&mut input1).expect("Failed to read line");
    let initial_temp: i32 = input1.trim().parse().expect("Invalid number");

    let mut input2 = String::new();
    std::io::stdin().read_line(&mut input2).expect("Failed to read line");
    let first_attempt: i32 = input2.trim().parse().expect("Invalid number");

    let mut input3 = String::new();
    std::io::stdin().read_line(&mut input3).expect("Failed to read line");
    let second_attempt: i32 = input3.trim().parse().expect("Invalid number");

    // TODO: Erstelle ein Thermostat mit der Anfangstemperatur

    // TODO: Gib die Anfangstemperatur aus
    // Format: "Initial: {temperature}"

    // TODO: Versuche, die erste Temperatur einzustellen und gib das Ergebnis aus
    // Format: "After setting to {attempted_value}: {temperature}"

    // TODO: Versuche, die zweite Temperatur einzustellen und gib das Ergebnis aus
    // Format: "After setting to {attempted_value}: {temperature}"
}
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