当前位置: 首页 > article >正文

【Rust自学】15.4. Drop trait:告别手动清理,释放即安全

喜欢的话别忘了点赞、收藏加关注哦(加关注即可阅读全文),对接下来的教程有兴趣的可以关注专栏。谢谢喵!(=・ω・=)
请添加图片描述

15.4.1. Drop trait的意义

类型如果实现了Drop trait,就可以让程序员自定义当值离开作用域时发生的操作。例如文件、网络资源的释放等。

在某些语言中(比如C/C++),对于某些类型,程序员每次使用完这些类型的实例时都必须写代码来释放内存或资源。如果忘记了,系统可能会过载并崩溃。在Rust中,程序员可以指定每当值超出范围时运行特定的代码,编译器将自动插入此代码。

任何类型都可以实现Drop trait,而Drop trait只要求实现drop方法,其参数是对self的可变引用。Drop trait在预导入模块(prelude),所以说使用它时不需要手动地引入。看个例子:

struct CustomSmartPointer {
    data: String,
}

impl Drop for CustomSmartPointer {
    fn drop(&mut self) {
        println!("Dropping CustomSmartPointer with data `{}`!", self.data);
    }
}

fn main() {
    let c = CustomSmartPointer {
        data: String::from("my stuff"),
    };
    let d = CustomSmartPointer {
        data: String::from("other stuff"),
    };
    println!("CustomSmartPointers created.");
}
  • 结构体CustomSmartPointer下有data字段,为String类型。
  • 通过impl Drop for CustomSmartPointerCustomSmartPointer实现了Drop trait。在其里面实现drop方法,参数是&mut self。这个方法通常是用于释放资源的,但出于演示的目的,这个方法里就只打印了一句话,把self里的data字段的数据打印出来。
  • main函数里创建了两个CustomSmartPointer的实例:c存的是"my stuff",d存的是other stuff。最后打印"CustomSmartPointers created."。

输出:

CustomSmartPointers created.
Dropping CustomSmartPointer with data `other stuff`!
Dropping CustomSmartPointer with data `my stuff`!

程序会先打印main函数的println!的内容,也就是"CustomSmartPointers created."。由于cd走出作用域都在第19行花括号后,所以程序接着会分别对cd调用drop函数。在实现Drop trait时定义的drop函数是打印一句话,所以这里cd就会分别打印一句话。

15.4.2. 使用std::mem::drop来提前drop

比较遗憾的是,我们很难直接禁用自动的drop功能,也没必要。因为Drop trait的目的就是进行自动的释放处理逻辑。

此外,Rust不允许手动调用Drop trait的drop方法。但是可以调用标准库的std::mem::drop函数来提前drop值,相当于提前调用了Drop trait的drop方法,它的参数是要丢弃的值。看个例子:

struct CustomSmartPointer {
    data: String,
}

impl Drop for CustomSmartPointer {
    fn drop(&mut self) {
        println!("Dropping CustomSmartPointer with data `{}`!", self.data);
    }
}

fn main() {
    let c = CustomSmartPointer {
        data: String::from("my stuff"),
    };
    let d = CustomSmartPointer {
        data: String::from("other stuff"),
    };
    drop(c);
    println!("CustomSmartPointers created.");
}

main函数中手动使用drop函数把c清理掉,而d还是自动清理的,这个时候的输出顺序应该是cd前。

输出:

Dropping CustomSmartPointer with data `my stuff`!
CustomSmartPointers created.
Dropping CustomSmartPointer with data `other stuff`!

这里有些人可能会提出疑问:c在走出作用域之前就被释放了,那么在走出作用域后编译器会不会再调用一次drop方法导致二次释放(double free)的错误呢?答案是不会,Rust的设计很安全,它的所有权系统会保证引用的有效,而drop也只会在确定不再使用这个值时被调用1次。


http://www.kler.cn/a/521195.html

相关文章:

  • 借DeepSeek-R1东风,开启创业新机遇
  • 进程通讯——类型和发展
  • 编程语言中的常见Bug及解决方案
  • PyTorch广告点击率预测(CTR)利用深度学习提升广告效果
  • 计算机网络 (61)移动IP
  • 单片机基础模块学习——PCF8591芯片
  • 1.24学习
  • 人工智能前沿技术进展与应用前景探究
  • 彻底理解JVM常量池
  • vue3中Teleport的用法以及使用场景
  • 【python】python基于机器学习与数据分析的二手手机特性关联与分类预测(源码+数据集)【独一无二】
  • Synology 群辉NAS安装(3)环境的准备工作
  • 【2025最新计算机毕业设计】基于SpringBoot+Vue爬虫技术的咖啡与茶饮料文化平台(高质量源码,可定制,提供文档,免费部署到本地)
  • WGCLOUD使用介绍 - 如何监控ActiveMQ和RabbitMQ
  • 在Ubuntu上用Llama Factory命令行微调Qwen2.5的简单过程
  • 【算法】数论基础——约数个数定理、约数和定理 python
  • 2024 开源社年度报告:拥抱开源新生活
  • 消息队列篇--扩展篇--码表及编码解码(理解字符字节和二进制,了解ASCII和Unicode,了解UTF-8和UTF-16,了解字符和二进制等具体转化过程等)
  • DroneXtract:一款针对无人机的网络安全数字取证工具
  • 从Stargate看全球科技变局与中国IT互联网的破局之路
  • 每日 Java 面试题分享【第 13 天】
  • 2025最新 Docker 国内可用镜像源仓库地址(01月02日更新)
  • 【UE】Level、World
  • Android AutoMotive--CarPropertyService
  • AIGC专栏18——EasyAnimateV5.1版本详解 应用Qwen2 VL作为文本编码器,支持轨迹控制与相机镜头控制
  • 【WebRTC - STUN/TURN服务 - COTURN配置】