Menu
Coddy logo textTech

Trait Drop

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

Gdy wartość w Rust wychodzi poza zakres, jest automatycznie czyszczona. A co, jeśli chcesz w tym momencie uruchomić własny kod, na przykład zapisać coś w dzienniku, zwolnić zasób lub wysłać końcową wiadomość? Cecha Drop pozwala dokładnie określić, co się stanie, gdy Twoja struktura ma zostać zniszczona.

Cecha Drop ma jedną metodę o nazwie drop, która przyjmuje &mut self:

struct Connection {
    id: u32,
}

impl Drop for Connection {
    fn drop(&mut self) {
        println!("Connection {} closed.", self.id);
    }
}

Nigdy nie wywołujesz bezpośrednio drop: Rust wywołuje ją automatycznie, gdy wartość wyjdzie poza zakres:

fn main() {
    let conn = Connection { id: 42 };
    println!("Using connection...");
}  // "Connection 42 closed." jest tutaj wypisywane automatycznie

Wynik będzie następujący:

Using connection...
Connection 42 closed.

To odpowiednik destruktora w Rust. Jest powszechnie używany do zadań związanych ze sprzątaniem: zamykania uchwytów do plików, rozłączania się z serwerami lub zwalniania zasobów, którymi Rust nie może zarządzać automatycznie. Cecha Drop gwarantuje, że kod sprzątający zostanie uruchomiony, nawet jeśli zakres zakończy się z powodu wcześniejszego zwrotu.

challenge icon

Wyzwanie

Łatwy

Zbudujmy system zarządzania zasobami, który demonstruje automatyczne sprzątanie! Utworzysz strukturę FileHandle, która symuluje otwieranie i zamykanie plików. Gdy uchwyt wyjdzie poza zakres, automatycznie poinformuje, że plik został zamknięty.

Rozmieścisz kod w dwóch plikach:

  • file_handle.rs: Zdefiniuj publiczną strukturę FileHandle z publicznym polem filename (String). Zaimplementuj funkcję skojarzoną new, która tworzy FileHandle i wyświetla komunikat, gdy plik zostaje "opened". Następnie zaimplementuj trait Drop, aby po usunięciu uchwytu wyświetlał komunikat o zamknięciu.
  • main.rs: Dołącz moduł file_handle i utwórz funkcję o nazwie process_file, która przyjmuje nazwę pliku, tworzy FileHandle w lokalnym zakresie i wyświetla komunikat o przetwarzaniu, gdy plik jest "open". Implementacja Drop uruchomi się automatycznie po zakończeniu zakresu. Wywołaj tę funkcję z podanym wejściem.

Po utworzeniu FileHandle powinien wyświetlić:

Opening file: {filename}

Podczas przetwarzania (wewnątrz zakresu) wyświetl:

Processing {filename}...

Po usunięciu FileHandle (zakończeniu zakresu) powinien wyświetlić:

Closing file: {filename}

Na przykład dla wejścia data.txt:

Opening file: data.txt
Processing data.txt...
Closing file: data.txt

A dla wejścia config.json:

Opening file: config.json
Processing config.json...
Closing file: config.json

Otrzymasz jedno wejście: ciąg znaków z nazwą pliku.

Spróbuj swoich sił

mod file_handle;

use file_handle::FileHandle;

// TODO: Zaimplementuj funkcję process_file
// Powinna ona:
// 1. Utworzyć lokalny zakres (używając nawiasów klamrowych {})
// 2. W tym zakresie utworzyć FileHandle za pomocą FileHandle::new()
// 3. Wyświetlić komunikat o przetwarzaniu: "Processing {filename}..."
// 4. Gdy zakres się zakończy, Drop zostanie wywołany automatycznie
fn process_file(filename: &str) {
    // TODO: Zaimplementuj tę funkcję
}

fn main() {
    let mut input = String::new();
    std::io::stdin().read_line(&mut input).expect("Failed to read line");
    let filename = input.trim();
    
    process_file(filename);
}
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