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.
Desafio
FácilVamos 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úblicaFileHandlecom um campo públicofilename(String). Implemente uma função associadanewque cria um FileHandle e imprime uma mensagem quando o arquivo é "aberto". Em seguida, implemente o traitDroppara 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 chamadaprocess_fileque 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.txtE com a entrada config.json:
Opening file: config.json
Processing config.json...
Closing file: config.jsonVocê receberá uma entrada: a string com o nome do arquivo.
REQUIRED OUTPUT FORMAT: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);
}
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
1Métodos e Comportamento
Introdução a Blocos de ImplementaçãoO Parâmetro SelfMétodos MutáveisFunções AssociadasMúltiplos Blocos de ImplementaçãoEncadeamento de MétodosRecapitulação - Ações de Retângulo4Projeto: Pet Virtual
Definindo o PetAlimentando o Pet7Traits Padrão
A Trait DebugA Trait DisplayClone e CopyTraits de IgualdadeRecapitulação - Ponto Imprimível10Projeto: Sistema de Documentos
A Trait DrawComponente de Texto2Encapsulamento e Módulos
Fundamentos de MódulosA Palavra-chave PublicCampos PrivadosGettersSettersRecapitulação - Cofre Seguro5Genéricos
Structs GenéricasMétodos GenéricosMúltiplos Tipos GenéricosFunções GenéricasRecapitulação - Ponto de Coordenada8Traits como Restrições
Sintaxe de Restrições de TraitRestrições MúltiplasA Cláusula WhereRetornando Tipos com TraitsRecapitulação - Impressora Genérica11Padrões de Projeto em Rust
Padrão NewtypeComposiçãoA Trait DropFrom e IntoRecapitulação - Mock de Smart Pointer3Enums Avançados
Enums com DadosMétodos em EnumsCorrespondência de Variantes de DadosO Enum Option RevisitadoRecapitulação - Enum Shape6Definição de Traits
O que é uma Trait?Implementando TraitsImplementações PadrãoSobrescrevendo PadrõesTraits com ParâmetrosRecapitulação - Media PlayerPratique por conta própria: Compilador de Rust online