借助 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 主要用来清理一些副作用,比如当变量被清理时我们需要取消正在进行的网络请求,关闭正在打开的文件等。
评论