РЕПЕТИТОР математика физика информатика
Для школьников и студентов. Подтягивание пробелов. ЦЭ, ЦТ, ОГЭ, ЕГЭ.
Идет набор на ЛЕТО. Жмите для подробностей:)
1238 of 1245 menu

Тип ManuallyDrop

Тип ManuallyDrop представляет собой обёртку над значением, которая предотвращает автоматический вызов деструктора (метода drop) при выходе переменной из области видимости. Этот тип полезен в ситуациях, когда необходимо вручную управлять временем жизни ресурсов, например, при работе с низкоуровневой памятью или при реализации коллекций. Параметром тип принимает значение любого типа T, для которого нужно отключить автоматическую очистку.

Важно понимать, что ManuallyDrop не делает само значение "безопасным" - он лишь снимает ответственность за вызов деструктора с компилятора и перекладывает её на программиста. Если забыть вручную освободить ресурсы, это приведёт к утечке памяти. Для ручного освобождения обычно используется метод drop из модуля std::mem или прямое чтение значения через unsafe.

Синтаксис

use std::mem::ManuallyDrop; let value = ManuallyDrop::new(data);

Также тип можно использовать в структурах и перечислениях, где он часто применяется для гибкого управления памятью.

Пример

Давайте создадим значение типа ManuallyDrop для строки и проверим, что деструктор не вызывается автоматически при выходе из области видимости:

use std::mem::ManuallyDrop; struct MyStruct { name: String, } impl Drop for MyStruct { fn drop(&mut self) { println!("Dropping {}", self.name); } } fn main() { let _normal = MyStruct { name: String::from("normal") }; let _manual = ManuallyDrop::new(MyStruct { name: String::from("manual") }); println!("End of main"); }

Результат выполнения кода:

End of main Dropping normal

Как видите, для переменной _normal деструктор был вызван автоматически, а для _manual - нет. Это привело к тому, что сообщение "Dropping manual" не было выведено.

Пример

Давайте вручную освободим ресурс, хранящийся в ManuallyDrop, используя метод drop:

use std::mem::ManuallyDrop; struct MyStruct { name: String, } impl Drop for MyStruct { fn drop(&mut self) { println!("Dropping {}", self.name); } } fn main() { let manual = ManuallyDrop::new(MyStruct { name: String::from("manual") }); println!("Before manual drop"); unsafe { ManuallyDrop::drop(&mut manual); } println!("After manual drop"); }

Результат выполнения кода:

Before manual drop Dropping manual After manual drop

Обратите внимание, что метод ManuallyDrop::drop является небезопасным, так как после его вызова значение считается перемещённым, и повторный вызов приведёт к неопределённому поведению.

Смотрите также

  • ключевое слово unsafe,
    которое позволяет выполнять небезопасные операции
  • функция drop,
    которая явно вызывает деструктор значения
  • функция forget,
    которая забывает значение без вызова деструктора
  • тип MaybeUninit,
    который представляет возможно неинициализированное значение
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить