Menu
Coddy logo textTech

El Trait Drop

Parte de la sección Object Oriented Programming del Journey de Rust de Coddy — lección 56 de 61.

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

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 de á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 utiliza comúnmente para tareas de limpieza: cerrar descriptores de archivos, desconectarse de servidores o liberar recursos que Rust no puede gestionar automáticamente. El trait Drop garantiza que el 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 estructura FileHandle que simula la apertura y el cierre de archivos; cuando el manejador salga del alcance, anunciará automáticamente que el archivo ha sido cerrado.

Organizarás tu código en dos archivos:

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

Cuando se crea un FileHandle, debe imprimir:

Opening file: {filename}

Mientras se procesa (dentro del alcance), imprime:

Processing {filename}...

Cuando el FileHandle es liberado (termina el alcance), 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 del archivo.

Hoja de referencia

El trait Drop te permite definir código de limpieza personalizado que se ejecuta automáticamente cuando un valor sale de su alcance.

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 de su alcance:

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

El trait Drop se utiliza comúnmente para tareas de limpieza como cerrar descriptores de archivos, desconectarse de servidores o liberar recursos. Garantiza que tu código de limpieza se ejecute, incluso si el alcance termina debido a un retorno anticipado.

Pruébalo tú mismo

mod file_handle;

use file_handle::FileHandle;

// TODO: Implementar 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: Implementar 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 Object Oriented Programming