Трейт Drop
Значения, которые реализуют Drop, могут задавать код, который выполняется, когда они выходят из области видимости:
// Copyright 2023 Google LLC
// SPDX-License-Identifier: Apache-2.0
struct Droppable {
name: &'static str,
}
impl Drop for Droppable {
fn drop(&mut self) {
println!("Dropping {}", 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!("Exiting innermost block");
}
println!("Exiting next block");
}
drop(a);
println!("Exiting main");
}
This slide should take about 8 minutes.
- Обратите внимание, что
std::mem::drop— не то же самое, чтоstd::ops::Drop::drop. - Значения автоматически освобождаются, когда выходят из области видимости.
- Когда значение освобождается, если оно реализует
std::ops::Drop, вызывается его реализацияDrop::drop. - Затем освобождаются все его поля, независимо от того, реализует ли он
Drop. std::mem::drop— просто пустая функция, которая принимает любое значение. Важно то, что она забирает владение значением, поэтому в конце своей области видимости оно освобождается. Так удобно явно освободить значения раньше, чем они выйдут из области видимости.- Это полезно для объектов, которые выполняют работу при
drop: освобождают блокировки, закрывают файлы и т. п.
- Это полезно для объектов, которые выполняют работу при
Темы для обсуждения:
- Почему
Drop::dropне принимаетself?- Коротко: если бы принимал,
std::mem::dropвызывался бы в конце блока, что привело бы к повторному вызовуDrop::dropи переполнению стека!
- Коротко: если бы принимал,
- Попробуйте заменить
drop(a)наa.drop().