Menu
Coddy logo textTech

Le trait Drop

Fait partie de la section Object Oriented Programming du Journey Rust de Coddy — leçon 56 sur 61.

Lorsqu'une valeur sort de la portée en Rust, elle est automatiquement nettoyée. Mais que se passe-t-il si vous devez exécuter du code personnalisé à ce moment-là — comme la journalisation, la libération d'une ressource ou l'envoi d'un message final ? Le trait Drop vous permet de définir exactement ce qui se passe lorsque votre structure est sur le point d'être détruite.

Le trait Drop possède une seule méthode appelée drop qui prend &mut self :

struct Connection {
    id: u32,
}

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

Vous n'appelez jamais drop directement — Rust l'appelle automatiquement lorsque la valeur sort de la portée :

fn main() {
    let conn = Connection { id: 42 };
    println!("Using connection...");
}  // "Connection 42 closed." s'affiche ici automatiquement

Le résultat serait :

Using connection...
Connection 42 closed.

C'est la version Rust d'un destructeur. Il est couramment utilisé pour les tâches de nettoyage : fermeture de descripteurs de fichiers, déconnexion de serveurs ou libération de ressources que Rust ne peut pas gérer automatiquement. Le trait Drop garantit que votre code de nettoyage s'exécute, même si la portée se termine en raison d'un retour anticipé.

challenge icon

Défi

Facile

Construisons un système de gestion de ressources qui démontre le nettoyage automatique ! Vous allez créer une structure FileHandle qui simule l'ouverture et la fermeture de fichiers—lorsque le handle sort de la portée (scope), il annoncera automatiquement que le fichier a été fermé.

Vous organiserez votre code sur deux fichiers :

  • file_handle.rs : Définissez une structure publique FileHandle avec un champ public filename (String). Implémentez une fonction associée new qui crée un FileHandle et affiche un message lorsque le fichier est "ouvert". Ensuite, implémentez le trait Drop de sorte que lorsque le handle est supprimé, il affiche un message de fermeture.
  • main.rs : Importez votre module file_handle et créez une fonction appelée process_file qui prend un nom de fichier, crée un FileHandle à l'intérieur d'une portée locale, et affiche un message de traitement pendant que le fichier est "ouvert". L'implémentation de Drop s'exécutera automatiquement à la fin de la portée. Appelez cette fonction avec l'entrée fournie.

Lorsqu'un FileHandle est créé, il doit afficher :

Opening file: {filename}

Pendant le traitement (à l'intérieur de la portée), affichez :

Processing {filename}...

Lorsque le FileHandle est supprimé (fin de la portée), il doit afficher :

Closing file: {filename}

Par exemple, avec l'entrée data.txt :

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

Et avec l'entrée config.json :

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

Vous recevrez une entrée : la chaîne de caractères du nom de fichier.

Aide-mémoire

Le trait Drop vous permet de définir du code de nettoyage personnalisé qui s'exécute automatiquement lorsqu'une valeur sort de la portée.

Le trait Drop possède une seule méthode appelée drop qui prend &mut self :

struct Connection {
    id: u32,
}

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

Vous n'appelez jamais drop directement — Rust l'appelle automatiquement lorsque la valeur sort de la portée :

fn main() {
    let conn = Connection { id: 42 };
    println!("Using connection...");
}  // "Connection 42 closed." s'affiche ici automatiquement

Le trait Drop est couramment utilisé pour des tâches de nettoyage comme la fermeture de descripteurs de fichiers, la déconnexion de serveurs ou la libération de ressources. Il garantit que votre code de nettoyage s'exécute, même si la portée se termine par un retour anticipé.

Essayez vous-même

mod file_handle;

use file_handle::FileHandle;

// TODO: Implémenter la fonction process_file
// Elle devrait :
// 1. Créer une portée locale (en utilisant des accolades {})
// 2. À l'intérieur de cette portée, créer un FileHandle en utilisant FileHandle::new()
// 3. Afficher le message de traitement : "Processing {filename}..."
// 4. Quand la portée se termine, Drop sera automatiquement appelé
fn process_file(filename: &str) {
    // TODO: Implémenter cette fonction
}

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 iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Object Oriented Programming