Menu
Coddy logo textTech

Pola prywatne

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

W poprzedniej lekcji wszystko było publiczne: struktura, jej pola i metody. Prawdziwe enkapsulowanie oznacza jednak kontrolowanie, w jaki sposób można uzyskać dostęp do danych. W Rust możesz upublicznić strukturę, zachowując jej pola jako prywatne.

Rozważmy Wallet, który nigdy nie powinien mieć ujemnego salda. Jeśli pole jest publiczne, każdy może ustawić je na dowolną wartość:

// wallet.rs
pub struct Wallet {
    balance: f64,  // Brak pub = prywatne!
}

impl Wallet {
    pub fn new(initial: f64) -> Wallet {
        Wallet { balance: initial }
    }
}

Zauważ, że Wallet jest publiczny, ale balance nie ma słowa kluczowego pub. Oznacza to, że kod spoza modułu może utworzyć Wallet za pomocą konstruktora, ale nie może bezpośrednio odczytać ani zmodyfikować pola salda:

// main.rs
mod wallet;
use wallet::Wallet;

fn main() {
    let w = Wallet::new(100.0);
    // println!("{}", w.balance);  // Błąd! Pole jest prywatne
    // w.balance = -50.0;          // Błąd! Nie można uzyskać dostępu do prywatnego pola
}

To jest podstawa enkapsulacji: struktura kontroluje własne dane. Kod zewnętrzny musi korzystać z udostępnionych przez Ciebie metod, co oznacza, że możesz dodać walidację, rejestrowanie lub dowolną inną logikę. Dane pozostają chronione przed nieprawidłowymi stanami.

W kolejnych lekcjach nauczysz się zapewniać kontrolowany dostęp do tych prywatnych danych za pomocą metod pobierających i ustawiających.

challenge icon

Wyzwanie

Łatwy

Zbudujmy system czujnika temperatury, który pokazuje enkapsulację, chroniąc wrażliwe dane wewnątrz modułu.

Utworzysz dwa pliki, aby uporządkować kod:

  • sensor.rs: Zdefiniuj strukturę TemperatureSensor z dwoma polami: location (String) i reading (f64). Struktura powinna być publiczna, aby można było jej używać z innych plików, ale oba pola pozostaw prywatne: kod zewnętrzny nie powinien mieć możliwości bezpośredniego dostępu do danych czujnika ani ich modyfikowania. Dodaj publiczny konstruktor new, który przyjmuje nazwę lokalizacji i początkowy odczyt temperatury.
  • main.rs: Dołącz moduł czujnika i utwórz TemperatureSensor za pomocą konstruktora. Ponieważ pola są prywatne, nie będzie można ich bezpośrednio wypisać; zamiast tego wypisz komunikat potwierdzający, że czujnik został pomyślnie utworzony.

To wyzwanie skupia się na podstawowej koncepcji prywatnych pól: struktura jest dostępna, ale jej wewnętrzne dane są chronione. Kod zewnętrzny może korzystać z czujnika tylko za pośrednictwem udostępnionych przez Ciebie metod (w tym przypadku jedynie konstruktora).

Wynik powinien mieć dokładnie następujący format:

Sensor created for: {location}

Aby uzyskać dostęp do lokalizacji i ją wypisać, funkcja new powinna wypisać ten komunikat przed zwróceniem czujnika, ponieważ samo pole jest prywatne.

Na przykład, jeśli utworzysz czujnik z lokalizacją "Kitchen" i odczytem 22.5, wynikiem będzie:

Sensor created for: Kitchen

Otrzymasz dwa dane wejściowe: nazwę lokalizacji i początkowy odczyt temperatury.

Spróbuj swoich sił

mod sensor;

use sensor::TemperatureSensor;

fn main() {
    // Wczytaj dane wejściowe
    let mut location = String::new();
    std::io::stdin().read_line(&mut location).expect("Failed to read line");
    let location = location.trim().to_string();
    
    let mut reading_str = String::new();
    std::io::stdin().read_line(&mut reading_str).expect("Failed to read line");
    let reading: f64 = reading_str.trim().parse().expect("Failed to parse reading");
    
    // TODO: Utwórz TemperatureSensor za pomocą konstruktora
    // Funkcja new zajmie się wyświetleniem komunikatu potwierdzającego
    
}
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