Menu
CoddyTech

Drop Trait

本课属于 Coddy Rust 学习旅程的“面向对象编程”单元。第 56 课,共 61 课。

在 Rust 中,当一个值超出作用域时,它会自动被清理。但如果你需要在此时运行自定义代码,比如记录日志、释放资源或发送最后一条消息,该怎么办?Drop trait 可以让你精确定义结构体即将被销毁时发生的事情。

Drop trait 只有一个名为 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 trait 能确保清理代码运行,即使作用域因提前返回而结束也一样。

challenge icon

挑战

简单

我们来构建一个资源管理系统,演示自动清理!你将创建一个 FileHandle 结构体,用来模拟打开和关闭文件。当句柄离开作用域时,它会自动提示文件已关闭。

你将把代码分成两个文件:

  • file_handle.rs:定义一个公开的 FileHandle 结构体,其中包含一个公开的 filename 字段(String)。实现一个 new 关联函数,用于创建 FileHandle,并在文件“opened”时打印一条消息。然后实现 Drop trait,使句柄被丢弃时打印一条关闭消息。
  • main.rs:引入 file_handle 模块,并创建一个名为 process_file 的函数。该函数接收一个文件名,在局部作用域中创建一个 FileHandle,并在文件“open”时打印一条处理消息。作用域结束时会自动运行 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::new() 创建一个 FileHandle
// 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 在线编译器