Menu
Coddy logo textTech

Settery

Część sekcji Programowanie obiektowe ścieżki Rust w Coddy. Lekcja 12 z 61.

Gettery pozwalają kodowi zewnętrznemu odczytywać prywatne dane. A co, jeśli chcesz pozwolić mu je zmieniać? Właśnie do tego służą metody setter: publiczne metody, które w kontrolowany sposób modyfikują prywatne pola.

Podstawowy setter przyjmuje &mut self i nową wartość:

// 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;
    }
}

W przeciwieństwie do metod odczytujących, metody ustawiające w Rust zwykle używają prefiksu set_, aby jasno wskazać, że modyfikują dane. Parametr &mut self jest niezbędny. Daje metodzie możliwość zmiany pól struktury.

Prawdziwa siła setterów tkwi w walidacji. Zamiast bezkrytycznie akceptować dowolną wartość, możesz egzekwować reguły:

pub fn set_balance(&mut self, amount: f64) {
    if amount >= 0.0 {
        self.balance = amount;
    }
    // Wartości ujemne są ignorowane bez powiadomienia
}

Teraz portfel chroni się sam: niezależnie od tego, jaką wartość próbuje ustawić kod zewnętrzny, saldo nigdy nie może być ujemne. Tak właśnie działa enkapsulacja: struktura kontroluje własne niezmienniki, a kod zewnętrzny po prostu nie może wprowadzić jej w nieprawidłowy stan.

challenge icon

Wyzwanie

Łatwy

Stwórzmy system termostatu, który pokazuje, jak metody ustawiające mogą egzekwować reguły, aby zachować poprawność danych. Termostat będzie mieć ustawienie temperatury, które można zmieniać tylko w bezpiecznym zakresie.

Utworzysz dwa pliki, aby uporządkować swój kod:

  • thermostat.rs: Zdefiniuj strukturę Thermostat z prywatnym polem temperature (i32). Struktura powinna być publiczna, ale pole pozostaje prywatne, aby chronić je przed nieprawidłowymi wartościami. Zaimplementuj:
    • Konstruktor new, który przyjmuje początkową temperaturę
    • Metodę pobierającą temperature, która zwraca bieżącą temperaturę
    • Metodę ustawiającą set_temperature, która akceptuje tylko wartości od 10 do 30 (włącznie). Jeśli wartość jest poza tym zakresem, temperatura powinna pozostać bez zmian.
  • main.rs: Dołącz moduł termostatu, utwórz termostat i pokaż walidację metody ustawiającej, próbując ustawić różne temperatury i wyświetlając wynik po każdej próbie.

Metoda ustawiająca powinna po cichu ignorować nieprawidłowe wartości: bez komunikatów o błędach, po prostu pozostaw bieżącą temperaturę bez zmian, gdy ktoś spróbuje ustawić wartość spoza prawidłowego zakresu.

Wynik powinien mieć dokładnie taki format:

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

Na przykład, jeśli utworzysz termostat z temperaturą 20, a następnie spróbujesz ustawić ją na 25 (prawidłowa wartość), a potem na 50 (nieprawidłowa wartość), wynikiem będzie:

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

Otrzymasz trzy dane wejściowe: początkową temperaturę, pierwszą temperaturę do ustawienia i drugą temperaturę do ustawienia.

Spróbuj swoich sił

mod thermostat;

use thermostat::Thermostat;

fn main() {
    // Wczytaj dane wejściowe
    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: Utwórz termostat z temperaturą początkową

    // TODO: Wyświetl temperaturę początkową
    // Format: "Initial: {temperature}"

    // TODO: Spróbuj ustawić pierwszą temperaturę i wyświetl wynik
    // Format: "After setting to {attempted_value}: {temperature}"

    // TODO: Spróbuj ustawić drugą temperaturę i wyświetl wynik
    // Format: "After setting to {attempted_value}: {temperature}"
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator Rust online