Menu
Coddy logo textTech

Трейт Drop

Часть раздела Объектно-ориентированное программирование путешествия по Rust на Coddy. Урок 56 из 61.

Когда значение выходит из области видимости в Rust, оно автоматически очищается. Но что, если в этот момент нужно выполнить пользовательский код, например записать данные в журнал, освободить ресурс или отправить финальное сообщение? Трейт Drop позволяет точно определить, что произойдёт, когда ваша структура будет уничтожена.

Трейт Drop имеет единственный метод called drop, который принимает &mut self:

struct Connection {
    id: u32,
}

impl Drop for Connection {
    fn drop(&mut self) {
        println!("Connection {} closed.", self.id);
    }
}

Ты никогда не вызываешь drop напрямую: Rust вызывает его automatically, когда значение выходит из области видимости:

fn main() {
    let conn = Connection { id: 42 };
    println!("Using connection...");
}  // "Connection 42 closed." печатается здесь автоматически

Результат будет таким:

Using connection...
Connection 42 closed.

Это версия деструктора в Rust. Обычно он используется для задач очистки: закрытия дескрипторов файлов, отключения от серверов или освобождения ресурсов, которыми Rust не может управлять автоматически. Трейт Drop гарантирует выполнение вашего кода очистки, даже если область видимости завершается из-за досрочного возврата.

challenge icon

Задание

Легко

Давайте создадим систему управления ресурсами, демонстрирующую автоматическую очистку! Вы создадите структуру FileHandle, которая имитирует открытие и закрытие файлов; когда дескриптор выйдет из области видимости, он автоматически сообщит, что file был закрыт.

Вы организуете код в двух файлах:

  • file_handle.rs: Определите публичную структуру FileHandle с публичным полем filename (String). Реализуйте ассоциированную function new, которая создаёт FileHandle и выводит сообщение, когда file "opened". Затем реализуйте трейт Drop, чтобы при удалении дескриптора он выводил сообщение о закрытии.
  • main.rs: Подключите свой модуль file_handle и создайте function с именем process_file, которая принимает имя file, создаёт FileHandle внутри локальной области видимости и выводит сообщение о processing, пока file "open". Реализация Drop автоматически запустится, когда область видимости закончится. Вызовите эту function с предоставленным input.

При создании FileHandle он должен вывести:

Opening file: {filename}

Во время processing (внутри области видимости) выведите:

Processing {filename}...

При удалении FileHandle (после завершения области видимости) он должен вывести:

Closing file: {filename}

Например, при input data.txt:

Opening file: data.txt
Processing data.txt...
Closing file: data.txt

А при input config.json:

Opening file: config.json
Processing config.json...
Closing file: config.json

Вы получите один input: строку с именем file.

ТРЕБУЕМЫЙ ФОРМАТ ВЫВОДА: [Ваш переведённый контент здесь]

Попробуйте сами

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);
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Объектно-ориентированное программирование

Потренируйтесь самостоятельно: Онлайн-компилятор Rust