Menu
Coddy logo textTech

El Trait Drop

Parte de la sección Programación Orientada a Objetos del Journey de Rust de Coddy. Lección 56 de 61.

Cuando un valor sale de ámbito en Rust, se limpia automáticamente. Pero ¿qué ocurre si necesitas ejecutar código personalizado en ese momento, como registrar información, liberar un recurso o enviar un mensaje final? El trait Drop te permite definir exactamente qué sucede cuando tu estructura está a punto de destruirse.

El trait Drop tiene un único método llamado drop que toma &mut self:

struct Connection {
    id: u32,
}

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

Nunca llamas a drop directamente: Rust lo llama automáticamente cuando el valor sale del ámbito:

fn main() {
    let conn = Connection { id: 42 };
    println!("Using connection...");
}  // "Connection 42 closed." se imprime aquí automáticamente

La salida sería:

Using connection...
Connection 42 closed.

Esta es la versión de Rust de un destructor. Se usa comúnmente para tareas de limpieza: cerrar identificadores de archivo, desconectarse de servidores o liberar recursos que Rust no puede gestionar automáticamente. El rasgo Drop garantiza que tu código de limpieza se ejecute, incluso si el ámbito termina debido a un retorno anticipado.

challenge icon

Desafío

Fácil

¡Vamos a construir un sistema de gestión de recursos que demuestre la limpieza automática! Crearás una struct FileHandle que simula la apertura y el cierre de archivos; cuando el handle salga del ámbito, anunciará automáticamente que el archivo ha sido cerrado.

Organizarás tu código en dos archivos:

  • file_handle.rs: Define una struct pública FileHandle con un campo público filename (String). Implementa una función asociada new que crea un FileHandle e imprime un mensaje cuando el archivo es "abierto". Luego implementa el trait Drop para que, cuando el handle se descarta, imprima un mensaje de cierre.
  • main.rs: Incorpora tu módulo file_handle y crea una función llamada process_file que toma un nombre de archivo, crea un FileHandle dentro de un ámbito local e imprime un mensaje de procesamiento mientras el archivo está "abierto". La implementación de Drop se ejecutará automáticamente cuando termine el ámbito. Llama a esta función con la entrada proporcionada.

Cuando se crea un FileHandle, debe imprimir:

Opening file: {filename}

Mientras se procesa (dentro del ámbito), imprime:

Processing {filename}...

Cuando el FileHandle se descarta (termina el ámbito), debe imprimir:

Closing file: {filename}

Por ejemplo, con la entrada data.txt:

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

Y con la entrada config.json:

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

Recibirás una entrada: la cadena del nombre de archivo.

Pruébalo tú mismo

mod file_handle;

use file_handle::FileHandle;

// TODO: Implementa la función process_file
// Debería:
// 1. Crear un ámbito local (usando llaves {})
// 2. Dentro de ese ámbito, crear un FileHandle usando FileHandle::new()
// 3. Imprimir el mensaje de procesamiento: "Processing {filename}..."
// 4. Cuando el ámbito termine, Drop se llamará automáticamente
fn process_file(filename: &str) {
    // TODO: Implementa esta función
}

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 iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Programación Orientada a Objetos

Practica por tu cuenta: Compilador de Rust online