Menu
Coddy logo textTech

A Trait Drop

Parte da seção Programação Orientada a Objetos do Journey de Rust da Coddy. Lição 56 de 61.

Quando um valor sai do escopo em Rust, ele é automaticamente limpo. Mas e se você precisar executar um código personalizado nesse momento, como registrar um log, liberar um recurso ou enviar uma mensagem final? A trait Drop permite definir exatamente o que acontece quando sua struct está prestes a ser destruída.

O trait Drop tem um único método chamado drop que recebe &mut self:

struct Connection {
    id: u32,
}

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

Você nunca chama drop diretamente: o Rust o chama automaticamente quando o valor sai do escopo:

fn main() {
    let conn = Connection { id: 42 };
    println!("Using connection...");
}  // "Connection 42 closed." imprime aqui automaticamente

A saída seria:

Using connection...
Connection 42 closed.

Esta é a versão do Rust de um destrutor. Ela é comumente usada para tarefas de limpeza: fechar identificadores de arquivo, desconectar-se de servidores ou liberar recursos que o Rust não consegue gerenciar automaticamente. O trait Drop garante que seu código de limpeza seja executado, mesmo que o escopo termine devido a um retorno antecipado.

challenge icon

Desafio

Fácil

Vamos criar um sistema de gerenciamento de recursos que demonstra a limpeza automática! Você criará uma struct FileHandle que simula a abertura e o fechamento de arquivos; quando o handle sair do escopo, ele anunciará automaticamente que o arquivo foi fechado.

Você organizará seu código em dois arquivos:

  • file_handle.rs: Defina uma struct pública FileHandle com um campo público filename (String). Implemente uma função associada new que cria um FileHandle e imprime uma mensagem quando o arquivo é "aberto". Em seguida, implemente o trait Drop para que, quando o handle for descartado, ele imprima uma mensagem de fechamento.
  • main.rs: Inclua seu módulo file_handle e crie uma função chamada process_file que recebe um nome de arquivo, cria um FileHandle dentro de um escopo local e imprime uma mensagem de processamento enquanto o arquivo está "aberto". A implementação de Drop será executada automaticamente quando o escopo terminar. Chame essa função com a entrada fornecida.

Quando um FileHandle for criado, ele deverá imprimir:

Opening file: {filename}

Durante o processamento (dentro do escopo), imprima:

Processing {filename}...

Quando o FileHandle for descartado (o escopo terminar), ele deverá imprimir:

Closing file: {filename}

Por exemplo, com a entrada data.txt:

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

E com a entrada config.json:

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

Você receberá uma entrada: a string com o nome do arquivo.

REQUIRED OUTPUT FORMAT: [Your translated content here]

Experimente você mesmo

mod file_handle;

use file_handle::FileHandle;

// TODO: Implemente a função process_file
// Ela deve:
// 1. Criar um escopo local (usando chaves {})
// 2. Dentro desse escopo, criar um FileHandle usando FileHandle::new()
// 3. Imprimir a mensagem de processamento: "Processing {filename}..."
// 4. Quando o escopo terminar, Drop será chamado automaticamente
fn process_file(filename: &str) {
    // TODO: Implemente esta função
}

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 iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Programação Orientada a Objetos

Pratique por conta própria: Compilador de Rust online