% Типаж Drop (сброс)

Мы обсудили типажи. Теперь давайте поговорим о конкретном типаже, предоставляемом стандартной библиотекой Rust. Этот типаж — Drop (сброс) — позволяет выполнить некоторый код, когда значение выходит из области видимости. Например:

struct HasDrop;

impl Drop for HasDrop {
    fn drop(&mut self) {
        println!("Сбрасываем!");
    }
}

fn main() {
    let x = HasDrop;

    // сделаем что-то

} // тут x выходит из области видимости

Когда x выходит из области видимости в конце main(), исполнится код реализации типажа Drop. У него один метод, который тоже называется drop(). Он принимает изменяемую ссылку на себя (self).

Вот и всё! Работа Drop достаточно проста, но есть несколько тонкостей. Например, значения сбрасываются в порядке, обратном порядку их объявления. Вот ещё пример:

struct Firework {
    strength: i32,
}

impl Drop for Firework {
    fn drop(&mut self) {
        println!("БАБАХ силой {}!!!", self.strength);
    }
}

fn main() {
    let firecracker = Firework { strength: 1 };
    let tnt = Firework { strength: 100 };
}

Этот код выведет следующее:

БАБАХ силой 100!!!
БАБАХ силой 1!!!

Сначала взрывается тринитротолуоловая бомба (tnt), потому что она была объявлена последней. За ней взрывается шутиха (firecracker). Первым вошёл, последним вышел.

Так зачем нужен Drop? Часто Drop используют, чтобы освободить ресурсы, представленные структурой (struct). Например, счётчик ссылок Arc<T> уменьшает число активных ссылок в drop(), и когда оно достигает нуля, освобождает хранимое значение.