借助 Drop trait 在清理时运行代码
前面我们学过,变量只在变量所在的作用域有效,离开了作用域,如果没有转移所有权的话,将被清理,Drop trait 允许我们在变量离开作用域时执行某些自定义操作。
实现 Drop trait
我们可以为我们的自定义类型实现 Drop trait:
#[derive(Debug)]
struct CustomSmartPointer {
data: String,
}
impl Drop for CustomSmartPointer {
fn drop(&mut self) {
println!("删除带有数据的`{}`的CustomSmartPointer!", self.data);
}
}
复制代码
drop 函数将在作用域结束时调用:
fn run() {
let c = CustomSmartPointer { data: String::from("c") };
let d = CustomSmartPointer { data: String::from("d") };
println!("CustomSmartPointers创建完成.");
// 下面rust将自动调用:(调用顺序是根据变量声明顺序,后进先出)
d.drop()
c.drop()
}
run();
// CustomSmartPointers创建完成.
// 删除带有数据的`d`的CustomSmartPointer!
// 删除带有数据的`c`的CustomSmartPointer!
复制代码
有时需要提前清理一个值。例如使用智能指针来管理锁时,强制运行 drop 方法来提前释放锁,从而允许同一作用域内的其他代码来获取它。
除了 rust 可以按上面规则自动清理变量,我们也可以使用 drop 函数手动清理:
fn run() {
let c = CustomSmartPointer { data: String::from("c") };
let d = CustomSmartPointer { data: String::from("d") };
println!("CustomSmartPointers创建完成.");
// 使用std::mem::drop提前清理值
use std::mem::drop;
drop(c);
// 清理之后将不能再使用
// println!("{:?}", c); // 报错,c已经被清理
println!("run函数调用完毕");
}
run();
// CustomSmartPointers创建完成.
// 删除带有数据的`c`的CustomSmartPointer!
// run函数调用完毕
// 删除带有数据的`d`的CustomSmartPointer!
复制代码
由于 c 在 run 函数结束直接就已经被手动清理了,所以在 run 函数结束的时候只会清理 d
有同学可能会想,是不是可以直接调用 trait 上的 drop 方法来清理数据呢?
fn run() {
let c = CustomSmartPointer { data: String::from("c") };
// 事实上rust并不允许手动调用Drop trait的drop方法
c.drop() // 报错
}
run();
复制代码
Drop trait 主要用来清理一些副作用,比如当变量被清理时我们需要取消正在进行的网络请求,关闭正在打开的文件等。
评论