O Trait Drop

Valores que implementam Drop podem especificar o código a ser executado quando saem do escopo:

struct Droppable {
    name: &'static str,
}

impl Drop for Droppable {
    fn drop(&mut self) {
        println!("Descartando {}", self.name);
    }
}

fn main() {
    let a = Droppable { name: "a" };
    {
        let b = Droppable { name: "b" };
        {
            let c = Droppable { name: "c" };
            let d = Droppable { name: "d" };
            println!("Saindo do bloco B");
        }
        println!("Saindo do bloco A");
    }
    drop(a);
    println!("Saindo do main");
}
This slide should take about 8 minutes.
  • Observe que std::mem::drop não é o mesmo que std::ops::Drop::drop.
  • Os valores são descartados automaticamente quando saem do escopo.
  • Quando um valor é descartado, se ele implementa std::ops::Drop então sua implementação Drop::drop será chamada.
  • Todas as seus campos serão descartadas também, independentemente de implementar Drop.
  • std::mem::drop é apenas uma função vazia que recebe qualquer valor. A importância é que ela assume a ownership do valor, então no final de seu escopo ele é descartado. Isso torna uma maneira conveniente de descartar explicitamente valores mais cedo do que eles sairiam do escopo.
    • Isso pode ser útil para objetos que fazem algum trabalho em drop: liberando travas, fechando arquivos, etc.

Pontos de discussão:

  • Por que Drop::drop não recebe self?
    • Resposta curta: Se recebesse, std::mem::drop seria chamado no final do bloco, resultando em outra chamada para Drop::drop ocasionando um estouro de pilha.
  • Tente substituir drop(a) por a.drop().