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 能确保清理代码运行,即使作用域因提前返回而结束也一样。
挑战
简单我们来构建一个资源管理系统,演示自动清理!你将创建一个 FileHandle 结构体,用来模拟打开和关闭文件。当句柄离开作用域时,它会自动提示文件已关闭。
你将把代码分成两个文件:
file_handle.rs:定义一个公开的FileHandle结构体,其中包含一个公开的filename字段(String)。实现一个new关联函数,用于创建 FileHandle,并在文件“opened”时打印一条消息。然后实现Droptrait,使句柄被丢弃时打印一条关闭消息。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);
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: Rust 在线编译器