Трейт Drop
Часть раздела Object Oriented Programming путешествия по Rust на Coddy — урок 56 из 61.
Когда значение выходит из области видимости в Rust, оно автоматически очищается. Но что, если вам нужно выполнить пользовательский код в этот момент — например, логирование, освобождение ресурса или отправку финального сообщения? Трейт Drop позволяет вам точно определить, что происходит, когда ваша структура вот-вот будет уничтожена.
Трейт Drop имеет единственный метод под названием drop, который принимает &mut self:
struct Connection {
id: u32,
}
impl Drop for Connection {
fn drop(&mut self) {
println!("Connection {} closed.", self.id);
}
}
Вы никогда не вызываете drop напрямую — Rust вызывает его автоматически, когда значение выходит из области видимости:
fn main() {
let conn = Connection { id: 42 };
println!("Using connection...");
} // "Connection 42 closed." выводится здесь автоматически
Результат будет следующим:
Using connection...
Connection 42 closed.
Это версия деструктора в Rust. Он обычно используется для задач очистки: закрытия дескрипторов файлов, отключения от серверов или освобождения ресурсов, которыми Rust не может управлять автоматически. Трейт Drop гарантирует выполнение вашего кода очистки, даже если область видимости завершается из-за раннего возврата.
Задание
ЛегкоДавайте создадим систему управления ресурсами, которая демонстрирует автоматическую очистку! Вы создадите структуру FileHandle, которая имитирует открытие и закрытие файлов — когда дескриптор выходит из области видимости, он автоматически сообщает о том, что файл был закрыт.
Вы организуете свой код в двух файлах:
file_handle.rs: Определите публичную структуруFileHandleс публичным полемfilename(String). Реализуйте ассоциированную функциюnew, которая создает FileHandle и выводит сообщение, когда файл «открыт». Затем реализуйте типажDrop, чтобы при удалении дескриптора выводилось сообщение о закрытии.main.rs: Подключите модуль file_handle и создайте функциюprocess_file, которая принимает имя файла, создает FileHandle внутри локальной области видимости и выводит сообщение об обработке, пока файл «открыт». Реализация Drop автоматически запустится по завершении области видимости. Вызовите эту функцию с предоставленными входными данными.
При создании FileHandle должно выводиться сообщение:
Opening file: {filename}Во время обработки (внутри области видимости) выведите:
Processing {filename}...Когда FileHandle удаляется (область видимости заканчивается), должно выводиться сообщение:
Closing file: {filename}Например, при входных данных data.txt:
Opening file: data.txt
Processing data.txt...
Closing file: data.txtИ при входных данных config.json:
Opening file: config.json
Processing config.json...
Closing file: config.jsonВы получите один входной параметр: строку с именем файла.
Попробуйте сами
mod file_handle;
use file_handle::FileHandle;
// TODO: Реализовать функцию process_file
// Она должна:
// 1. Создать локальную область видимости (используя фигурные скобки {})
// 2. Внутри этой области создать FileHandle, используя FileHandle::new()
// 3. Вывести сообщение об обработке: "Processing {filename}..."
// 4. Когда область видимости закончится, Drop будет вызван автоматически
fn process_file(filename: &str) {
// TODO: Реализовать эту функцию
}
fn main() {
let mut input = String::new();
std::io::stdin().read_line(&mut input).expect("Failed to read line");
let filename = input.trim();
process_file(filename);
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Object Oriented Programming
1Методы и поведение
Введение в блоки реализацииПараметр SelfИзменяемые методыАссоциированные функцииНесколько блоков реализацииЦепочки вызовов методовИтоги: действия с Rectangle4Проект: Виртуальный питомец
Определение питомцаКормление питомца2Инкапсуляция и модули
Основы модулейКлючевое слово PublicПриватные поляГеттерыСеттерыИтоги — Безопасный сейф5Обобщения
Обобщённые структурыОбобщённые методыНесколько обобщённых типовОбобщённые функцииПовторение — Координатная точка8Трейты как ограничения
Синтаксис ограничений трейтовМножественные ограниченияКонструкция whereВозврат типов с трейтамиИтоги — Обобщённый принтер11Паттерны проектирования в Rust
Паттерн NewtypeКомпозицияТрейт DropFrom и IntoИтоги — Мок-объект Smart Pointer3Продвинутые перечисления
Перечисления с даннымиМетоды в перечисленияхСопоставление вариантов с даннымиСнова об Option EnumИтоги — перечисление Shape6Определение трейтов
Что такое трейт?Реализация трейтовРеализации по умолчаниюПереопределение реализаций по умолчаниюТрейты с параметрамиИтоги — Media Player