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.
Wyzwanie
ŁatwyZbudujmy 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ęFileHandlez publicznym polemfilename(String). Zaimplementuj funkcję skojarzonąnew, która tworzy FileHandle i wyświetla komunikat, gdy plik zostaje "opened". Następnie zaimplementuj traitDrop, aby po usunięciu uchwytu wyświetlał komunikat o zamknięciu.main.rs: Dołącz moduł file_handle i utwórz funkcję o nazwieprocess_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.txtA dla wejścia config.json:
Opening file: config.json
Processing config.json...
Closing file: config.jsonOtrzymasz 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);
}
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Programowanie obiektowe
1Metody i zachowanie
Wprowadzenie do bloków implementacjiParametr selfMetody modyfikująceFunkcje powiązaneWiele bloków implementacjiŁańcuchowe wywoływanie metodPowtórzenie — działania na prostokącie4Projekt: Wirtualne zwierzątko
Definiowanie zwierzątkaKarmienie zwierzątka7Standardowe cechy
Cecha DebugCecha DisplayClone i CopyCechy równościPowtórka – punkt do wydrukowania10Projekt: System dokumentów
Trait DrawKomponent tekstowy2Hermetyzacja i moduły
Podstawy modułówSłowo kluczowe publicPola prywatneGetterySetteryPodsumowanie — bezpieczna skrytka5Typy generyczne
Struktury generyczneMetody generyczneWiele typów generycznychFunkcje generycznePodsumowanie – punkt współrzędnych8Cechy jako ograniczenia
Składnia ograniczeń cechWiele ograniczeńKlauzula whereZwracanie typów z użyciem cechPodsumowanie — generyczna drukarka11Wzorce projektowe w Rust
Wzorzec NewtypeKompozycjaTrait DropFrom i IntoPodsumowanie — atrapowy inteligentny wskaźnik3Zaawansowane typy wyliczeniowe
Typy wyliczeniowe z danymiMetody typów wyliczeniowychDopasowywanie wariantów danychTyp wyliczeniowy Option — powtórzeniePodsumowanie — typ wyliczeniowy Shape6Definiowanie cech
Czym jest cecha?Implementowanie cechImplementacje domyślneNadpisywanie wartości domyślnychCechy z parametramiPowtórzenie — odtwarzacz multimedialnyPoćwicz samodzielnie: Kompilator Rust online