Das Drop-Trait
Teil des Abschnitts Object Oriented Programming der Rust-Journey von Coddy — Lektion 56 von 61.
Wenn ein Wert in Rust den Gültigkeitsbereich verlässt, wird er automatisch bereinigt. Aber was ist, wenn Sie in diesem Moment benutzerdefinierten Code ausführen müssen – zum Beispiel zum Protokollieren, Freigeben einer Ressource oder Senden einer letzten Nachricht? Das Drop-Trait ermöglicht es Ihnen, genau zu definieren, was passiert, wenn Ihr Struct kurz davor steht, zerstört zu werden.
Das Drop-Trait besitzt eine einzige Methode namens drop, die &mut self entgegennimmt:
struct Connection {
id: u32,
}
impl Drop for Connection {
fn drop(&mut self) {
println!("Connection {} closed.", self.id);
}
}
Man ruft drop niemals direkt auf – Rust ruft es automatisch auf, wenn der Wert den Gültigkeitsbereich verlässt:
fn main() {
let conn = Connection { id: 42 };
println!("Using connection...");
} // "Connection 42 closed." wird hier automatisch ausgegeben
Die Ausgabe wäre:
Using connection...
Connection 42 closed.
Dies ist Rusts Version eines Destruktors. Er wird häufig für Bereinigungsaufgaben verwendet: das Schließen von Dateihandles, das Trennen von Verbindungen zu Servern oder das Freigeben von Ressourcen, die Rust nicht automatisch verwalten kann. Das Drop-Trait garantiert, dass Ihr Bereinigungscode ausgeführt wird, selbst wenn der Gültigkeitsbereich aufgrund einer vorzeitigen Rückgabe endet.
Aufgabe
EinfachLassen Sie uns ein Ressourcenverwaltungssystem bauen, das die automatische Bereinigung demonstriert! Sie werden ein FileHandle-Struct erstellen, das das Öffnen und Schließen von Dateien simuliert – wenn das Handle den Gültigkeitsbereich verlässt, wird es automatisch ankündigen, dass die Datei geschlossen wurde.
Sie werden Ihren Code auf zwei Dateien aufteilen:
file_handle.rs: Definieren Sie ein öffentlichesFileHandle-Struct mit einem öffentlichenfilename-Feld (String). Implementieren Sie eine assoziierte Funktionnew, die ein FileHandle erstellt und eine Nachricht ausgibt, wenn die Datei "opened" wird. Implementieren Sie dann dasDrop-Trait, sodass beim Löschen des Handles eine Abschlussmeldung ausgegeben wird.main.rs: Binden Sie Ihr file_handle-Modul ein und erstellen Sie eine Funktion namensprocess_file, die einen Dateinamen entgegennimmt, ein FileHandle innerhalb eines lokalen Gültigkeitsbereichs erstellt und eine Verarbeitungsnachricht ausgibt, während die Datei "open" ist. Die Drop-Implementierung wird automatisch ausgeführt, wenn der Gültigkeitsbereich endet. Rufen Sie diese Funktion mit der bereitgestellten Eingabe auf.
Wenn ein FileHandle erstellt wird, sollte es Folgendes ausgeben:
Opening file: {filename}Während der Verarbeitung (innerhalb des Gültigkeitsbereichs), geben Sie Folgendes aus:
Processing {filename}...Wenn das FileHandle verworfen wird (Gültigkeitsbereich endet), sollte es Folgendes ausgeben:
Closing file: {filename}Zum Beispiel mit der Eingabe data.txt:
Opening file: data.txt
Processing data.txt...
Closing file: data.txtUnd mit der Eingabe config.json:
Opening file: config.json
Processing config.json...
Closing file: config.jsonSie erhalten eine Eingabe: den Dateinamen-String.
Spickzettel
Das Drop-Trait ermöglicht es Ihnen, benutzerdefinierten Bereinigungscode zu definieren, der automatisch ausgeführt wird, wenn ein Wert den Gültigkeitsbereich verlässt.
Das Drop-Trait hat eine einzige Methode namens drop, die &mut self entgegennimmt:
struct Connection {
id: u32,
}
impl Drop for Connection {
fn drop(&mut self) {
println!("Connection {} closed.", self.id);
}
}
Sie rufen drop niemals direkt auf – Rust ruft es automatisch auf, wenn der Wert den Gültigkeitsbereich verlässt:
fn main() {
let conn = Connection { id: 42 };
println!("Using connection...");
} // "Connection 42 closed." wird hier automatisch ausgegeben
Das Drop-Trait wird häufig für Bereinigungsaufgaben wie das Schließen von Dateihandles, das Trennen von Serververbindungen oder das Freigeben von Ressourcen verwendet. Es garantiert, dass Ihr Bereinigungscode ausgeführt wird, selbst wenn der Gültigkeitsbereich aufgrund einer vorzeitigen Rückgabe endet.
Probier es selbst
mod file_handle;
use file_handle::FileHandle;
// TODO: Implementiere die process_file Funktion
// Sie sollte:
// 1. Einen lokalen Scope erstellen (mit geschweiften Klammern {})
// 2. Innerhalb dieses Scopes ein FileHandle mit FileHandle::new() erstellen
// 3. Die Verarbeitungsnachricht ausgeben: "Processing {filename}..."
// 4. Wenn der Scope endet, wird Drop automatisch aufgerufen
fn process_file(filename: &str) {
// TODO: Implementiere diese Funktion
}
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);
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Object Oriented Programming
1Methoden und Verhalten
Einführung in ImplementierungsblöckeDer Self-ParameterVeränderliche MethodenAssoziierte FunktionenMehrere ImplementierungsblöckeMethod ChainingRückblick – Rechteck-Aktionen4Projekt: Virtuelles Haustier
Das Haustier definierenDas Haustier füttern7Standard-Traits
Das Debug-TraitDas Display-TraitClone und CopyGleichheits-TraitsZusammenfassung – Druckbarer Punkt10Projekt: Dokumentensystem
Das Draw-TraitText-Komponente2Kapselung und Module
Grundlagen der ModuleDas Public-SchlüsselwortPrivate FelderGetterSetterWiederholung – Sicherer Tresor5Generics
Generische StructsGenerische MethodenMehrere generische TypenGenerische FunktionenZusammenfassung - Koordinatenpunkt8Traits als Einschränkungen
Syntax für Trait BoundsMehrfache BoundsDie Where-KlauselTypen mit Traits zurückgebenRückblick – Generischer Drucker11Design Patterns in Rust
Newtype-PatternKompositionDas Drop-TraitFrom und IntoZusammenfassung – Smart Pointer Mock3Fortgeschrittene Enums
Enums mit DatenMethoden für EnumsMatching von DatenvariantenDas Option-Enum erneut betrachtetZusammenfassung – Shape-Enum6Definition von Traits
Was ist ein Trait?Traits implementierenStandardimplementierungenStandardimplementierungen überschreibenTraits mit ParameternZusammenfassung – Media Player