Трейт Drop
Трейт Drop определяет метод drop,
который автоматически вызывается, когда значение
выходит из области видимости или удаляется.
Это позволяет освободить ресурсы: закрыть файл,
освободить память, разблокировать мьютекс и так далее.
Метод drop принимает изменяемую ссылку
на self и не возвращает значения.
Компилятор Rust автоматически вызывает drop
для каждого значения, покидающего свою область видимости.
Порядок вызова обратный порядку создания значений.
Трейт Drop нельзя реализовать для типов,
которые реализуют трейт Copy.
Также существует функция std::mem::drop,
которая позволяет принудительно уничтожить значение
до выхода из области видимости.
Синтаксис
impl Drop for TypeName
{
fn drop(&mut self)
{
// код освобождения ресурсов
}
}
Пример
Давайте создадим структуру, которая выводит сообщение при удалении значения:
struct MyStruct
{
name: String,
}
impl Drop for MyStruct
{
fn drop(&mut self)
{
println!("Dropping: {}", self.name);
}
}
fn main()
{
let a = MyStruct { name: String::from("abcde") };
let b = MyStruct { name: String::from("12345") };
println!("End of main");
}
Результат выполнения кода:
End of main
Dropping: 12345
Dropping: abcde
Как видите, значения удаляются в обратном порядке относительно их создания.
Пример
Давайте используем функцию std::mem::drop
для принудительного уничтожения значения:
struct MyStruct
{
name: String,
}
impl Drop for MyStruct
{
fn drop(&mut self)
{
println!("Dropping: {}", self.name);
}
}
fn main()
{
let a = MyStruct { name: String::from("abcde") };
println!("Before drop");
drop(a);
println!("After drop");
}
Результат выполнения кода:
Before drop
Dropping: abcde
After drop
Пример
Давайте посмотрим, как Drop работает
с полями структуры. Поля удаляются после
выполнения метода drop:
struct Inner
{
name: String,
}
impl Drop for Inner
{
fn drop(&mut self)
{
println!("Dropping Inner: {}", self.name);
}
}
struct Outer
{
inner: Inner,
}
impl Drop for Outer
{
fn drop(&mut self)
{
println!("Dropping Outer");
}
}
fn main()
{
let _o = Outer {
inner: Inner { name: String::from("12345") },
};
println!("End of main");
}
Результат выполнения кода:
End of main
Dropping Outer
Dropping Inner: 12345
Смотрите также
-
трейт
Copy,
который позволяет копировать значения вместо перемещения -
трейт
Clone,
который позволяет явно создавать копии значений -
концепция
владения,
которая определяет, кто отвечает за удаление значения -
операция
перемещения,
которая передаёт владение значением другому владельцу