RAII (Resource Acquisition Is Initialization) — идиома, пришедшая из C++, по которой время жизни ресурса строго связано с временем жизни объекта в стеке. В Rust эта концепция легла в основу системы владения и освобождения ресурсов, что позволяет обходиться без классических сборщиков мусора (GC).
Многие языки управляют памятью и ресурсами с помощью сборщика мусора, который периодически "подчищает" ненужные объекты. Эта стратегия увеличивает задержки и не дает гарантий моментального освобождения внешних ресурсов (файлы, сокеты и т.д.). В низкоуровневом и системном программировании такая ситуация недопустима: нужна точность и детерминированность управления ресурсом.
В Rust каждый объект владеет своим ресурсом и освобождает его строго по месту разрушения (out of scope), через вызов Drop (аналог деструктора). Как итог, ресурсы освобождаются немедленно, а все ошибки неявного освобождения сводятся к минимуму. Система типов и владения Rust предотвращает утечки и двойное освобождение почти на этапе компиляции.
Пример кода:
struct FileWrapper { file: std::fs::File, } impl Drop for FileWrapper { fn drop(&mut self) { println!("FileWrapper закрывает файл! (scope exit)"); } } fn main() { let _fw = FileWrapper { file: std::fs::File::create("test.txt").unwrap() }; // При выходе из main, drop гарантированно вызывается }
Ключевые особенности:
Вызывается ли Drop для значений, которые были перемещены (moved) ранее?
Нет, после перемещения значения вызывается Drop только для нового владельца, старый объект считается "пустым" и Drop не срабатывает.
let file1 = FileWrapper {...}; let file2 = file1; // file1 move // Drop вызовется один раз — для file2
Может ли panic! или unwrap() в середине области видимости препятствовать вызову drop?
Нет, паника или выход по ошибке не отменяют вызов деструктора — Drop вызовется обязательно для всех вышедших из области объектов.
Если ссылка владеет объектом, вызовется ли drop при завершении времени жизни ссылки?
Нет, drop вызывается только для владельца объекта, ссылки владения не осуществляют. Для heap-ресурсов нужен smart pointer.
Разработчик передал дескриптор файла по ссылке в функцию на запись. После завершения работы программы у файла остался lock, потому что drop не вызвался (не было владельца, использовалась ссылка).
Плюсы:
Минусы:
Владение ресурсом всегда передавалось структурами, реализующими Drop. Все открытые файлы, соединения или локи освобождаются автоматом при завершении scope или panic. Карт-бланш на безопасное и тривиальное управление ресурсами даже в сложных проектах.
Плюсы:
Минусы: