Menu
Coddy logo textTech

Setter

Teil des Abschnitts Objektorientierte Programmierung der Rust-Journey von Coddy. Lektion 12 von 61.

Getter ermöglichen es externem Code, private Daten zu lesen. Aber was, wenn du ihm erlauben musst, sie zu ändern? Hier kommen Setter-Methoden ins Spiel: öffentliche Methoden, die private Felder auf kontrollierte Weise ändern.

Ein grundlegender 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 getter verwenden Rust setter typischerweise das Präfix set_, um eindeutig anzuzeigen, dass sie Daten ändern. Der Parameter &mut self ist wesentlich. Er erteilt der Methode die Berechtigung, die Felder der Struktur zu ändern.

Die eigentliche Stärke von Settern ist die Validierung. Statt jeden Wert blind zu akzeptieren, kannst du Regeln durchsetzen:

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

Jetzt schützt sich die Geldbörse selbst: Unabhängig davon, welchen Wert externer Code zu setzen versucht, kann der balance niemals negativ werden. Das ist Kapselung in Aktion: Die Struktur kontrolliert ihre eigenen Invarianten, und externer Code kann sie einfach nicht in einen ungültigen Zustand versetzen.

challenge icon

Aufgabe

Einfach

Erstellen wir ein Thermostatsystem, das zeigt, wie Setter Regeln durchsetzen können, um Daten gültig zu halten. Dein Thermostat wird eine Temperatureinstellung haben, die nur innerhalb eines sicheren Bereichs angepasst werden kann.

Du wirst zwei Dateien erstellen, um deinen Code zu organisieren:

  • thermostat.rs: Definiere eine Thermostat-Struktur mit einem privaten Feld temperature (i32). Die Struktur sollte öffentlich sein, aber das Feld bleibt privat, um es vor ungültigen Werten zu schützen. Implementiere:
    • 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: Binde dein Thermostatmodul ein, erstelle ein Thermostat und demonstriere die Validierung des Setters, indem du versuchst, verschiedene Temperaturen zu setzen, und nach jedem Versuch das Ergebnis ausgibst.

Der Setter sollte ungültige Werte stillschweigend ignorieren: keine Fehlermeldungen, sondern einfach die aktuelle Temperatur unverändert lassen, wenn jemand versucht, sie außerhalb des gültigen Bereichs zu setzen.

Deine Ausgabe sollte genau diesem Format folgen:

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

Wenn du beispielsweise ein Thermostat mit 20 erstellst und dann versuchst, es auf 25 (gültig) und anschließend auf 50 (ungültig) zu setzen, würde die Ausgabe wie folgt aussehen:

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

Du erhältst drei Eingaben: die Anfangstemperatur, die erste Temperatur, die versucht werden soll, und die zweite Temperatur, die versucht werden soll.

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 das Ergebnis auszugeben
    // Format: "After setting to {attempted_value}: {temperature}"

    // TODO: Versuche, die zweite Temperatur einzustellen und das Ergebnis auszugeben
    // 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 Objektorientierte Programmierung

Übe selbstständig: Online-Rust-Compiler