El trait Drop permite definir una lógica personalizada de limpieza de recursos cuando sale del ámbito. Normalmente se utiliza para liberar recursos de archivos, redes, externos y no seguros. Drop se llama automáticamente por el compilador.
Ejemplo:
struct FileWrapper { fd: i32, } impl Drop for FileWrapper { fn drop(&mut self) { println!("Cerrando fd: {}", self.fd); unsafe { libc::close(self.fd); } } } fn main() { let file = FileWrapper { fd: 42 }; } // drop se llama automáticamente
Características:
file.drop(), pero se puede llamar a través de std::mem::drop(file).panic!) dentro de drop; esto llevará a un "double panic" y a la terminación del proceso.Pregunta: ¿Qué sucederá si en el proceso de drop() de una estructura intenta transferir la propiedad de un recurso a otra parte del programa, por ejemplo, devolverlo desde drop?
Respuesta: No se puede "salvar" o transferir el valor de un campo de la estructura durante drop a nadie más que a drop mismo; intentar devolver un valor o transferirlo resultará en un error de compilación o en una violación de la seguridad de memoria (si se usa unsafe). Ejemplo de error:
impl Drop for MyStruct { fn drop(&mut self) -> T { // Error: Drop::drop no puede devolver un valor! ... } }
Historia
En un procesador de archivos, olvidaron implementar Drop para una estructura que envuelve directamente un descriptor de archivo sin procesar. Después de cientos de operaciones, surgía "se agotó el límite de descriptores de archivos"; los recursos no se limpiaban.
Historia
En una biblioteca de red, implementaron Drop para un envoltorio sobre una conexión TCP, pero al hacer drop se producía un panic debido a un error al cerrar el socket. Esto provocaba la terminación del hilo debido a un double-panic (la única forma - evitar panic en Drop!).
Historia
En un sistema de plugins, intentaron implementar la limpieza utilizando Drop, creando nuevos recursos durante drop (por ejemplo, registrando en un archivo). Esto llevó a "ya prestado: BorrowMutError" debido a la llamada recursiva a drop para estructuras relacionadas y fugas de recursos.