2022-10-29:go语言中的defer能非常方便地处理资源释放问题,rust语言里如何实现defer功能呢?

答案2022-10-29:

rust里有时候你也必须用defer,别说是设计上的问题,因为这种情况你肯定会遇到。

有些时候第三方的结构体,析构函数是不满足需求的,但你也不可能直接修改源码。

第三方的结构体是无法直接实现Drop的,因此只能另外定义结构体来包裹第三方的结构体,然后实现drop,这样就能实现defer功能。这是装饰器模式。

现在已经有现成的轮子,直接用就行。轮子有scopeguard和xjbutil。

scopeguard案例代码如下:

extern crate scopeguard;
struct AA {
a: i32,
b: i32,
} fn main() {
println!("scopeguard");
let mut a = AA { a: 1, b: 2 };
println!("外部1----{:p}", &(a));
println!("外部1----{:p}", &(a.a));
println!("外部1----{}", a.a); let mut a = scopeguard::guard(&mut a, |a| {
a.a = 13;
println!("内部1----{:p}", &a);
println!("内部1----{:p}", &a.a);
println!("内部1----{}", a.a);
}); //let mut a = a; let mut a = scopeguard::guard(&mut a, |a| {
a.a = 14;
println!("内部2----{:p}", &a);
println!("内部2----{:p}", &a.a);
println!("内部2----{}", a.a);
}); //let mut a = a;
a.a = 2;
println!("外部2----{:p}", &a);
println!("外部2----{:p}", &a.a);
println!("外部2----{}", a.a); let mut a = scopeguard::guard(&mut a, |a| {
a.a = 15;
println!("内部3----{:p}", &a);
println!("内部3----{:p}", &a.a);
println!("内部3----{}", a.a);
}); //let mut a = a; println!("外部3----{:p}", &(a));
println!("外部3----{:p}", &(a.a));
println!("外部3----{}", a.a);
}

xjbutil案例代码如下:

use xjbutil::defer;
struct AA {
a: i32,
b: i32,
} fn main() {
println!("xjbutil");
let mut a = AA { a: 1, b: 2 };
println!("外部0----{:p}", &(a));
println!("外部0----{:p}", &(a.a));
println!("外部0----{}", a.a); let a = &mut a;
println!("外部1----{:p}", &(a));
println!("外部1----{:p}", &(a.a));
println!("外部1----{}", a.a); defer!(
|mut aa| {
aa.a = 13;
println!("内部1----{:p}", &aa);
println!("内部1----{:p}", &aa.a);
println!("内部1----{}", aa.a);
},
a
); defer!(
|mut a| {
a.a = 14;
println!("内部2----{:p}", &a);
println!("内部2----{:p}", &a.a);
println!("内部2----{}", a.a);
},
a
); a.a = 2;
println!("外部2----{:p}", &a);
println!("外部2----{:p}", &a.a);
println!("外部2----{}", a.a); defer!(
|mut a| {
a.a = 15;
println!("内部3----{:p}", &a);
println!("内部3----{:p}", &a.a);
println!("内部3----{}", a.a);
},
a
); println!("外部3----{:p}", &(a));
println!("外部3----{:p}", &(a.a));
println!("外部3----{}", a.a);
}

结果如下:

2022-10-29:go语言中的defer能非常方便地处理资源释放问题,rust语言里如何实现defer功能呢?的更多相关文章

  1. C语言中string char int类型转换

    C语言中string -- ::) 转载 ▼ 标签: 操作符 int char c语言 类型转换 分类: C/Cpp ,char型数字转换为int型 "; printf(]-');//输出结 ...

  2. Go语言中的defer

    可以用作一些资源的释放. 1.在一个函数内的defer执行顺序是先写的后执行,后写的先执行(遵循栈结构) func DeferTest1(){ defer fmt.Println("我是 d ...

  3. Go语言中defer语句使用小结

    defer是Go语言中的延迟执行语句,用来添加函数结束时执行的代码,常用于释放某些已分配的资源.关闭数据库连接.断开socket连接.解锁一个加锁的资源.Go语言机制担保一定会执行defer语句中的代 ...

  4. C语言中do...while(0)的妙用(转载)

    转载来自:C语言中do...while(0)的妙用,感谢分享. 在linux内核代码中,经常看到do...while(0)的宏,do...while(0)有很多作用,下面举出几个: 1.避免goto语 ...

  5. 在不同语言中static的用法

    static (计算机高级语言) 编辑 像在VB,C#,C,C++,Java,PHP中我们可以看到static作为关键字和函数出现,在其他的高级计算机语言如FORTRAN.ALGOL.COBOL.BA ...

  6. C语言中setjmp与longjmp学习笔记

    C语言中setjmp与longjmp学习笔记 一.基础介绍 头文件:#include<setjmp.h> 原型:  int setjmp(jmp_buf envbuf) ,然而longjm ...

  7. C语言中,头文件和源文件的关系(转)

    简单的说其实要理解C文件与头文件(即.h)有什么不同之处,首先需要弄明白编译器的工作过程,一般说来编译器会做以下几个过程: 1.预处理阶段 2.词法与语法分析阶段 3.编译阶段,首先编译成纯汇编语句, ...

  8. C++中函数的默认参数和C语言中volatile的学习

    1.函数默认参数 1 int func(int a,int b=10) 2 { 3 return a*b; 4 } 5 6 int main() 7 { 8 int c=func(2); 9 cout ...

  9. 转:C语言中的static变量和C++静态数据成员(static member)

    转自:C语言中的static变量和C++静态数据成员(static member) C语言中static的变量:1).static局部变量        a.静态局部变量在函数内定义,生存期为整个程序 ...

  10. C语言中.h和.c文件解析(很精彩)

    C语言中.h和.c文件解析(很精彩)   简单的说其实要理解C文件与头文件(即.h)有什么不同之处,首先需要弄明白编译器的工作过程,一般说来编译器会做以下几个过程: 1.预处理阶段 2.词法与语法分析 ...

随机推荐

  1. GRAPH ATTENTION NETWORKS(GAT)图注意力网络

    摘要: 我们提出一个图注意力网络,一个新的用来操作图结构数据的神经网络结构,它利用"蒙面"的自我注意力层来解决基于图卷积以及和它类似结构的短板.通过堆叠一些层,这些层的节点能够参与 ...

  2. SpringBoot笔记--事件监听+启动流程+监控+项目部署

    事件监听 ApplicationContextInitializer SpringApplicationRunListener ApplicationRunner CommandLineRunner ...

  3. Go语言:利用 TDD 测试驱动开发帮助理解数组与动态数组(切片)的区别

    Array VS Slice 数组允许你以特定的顺序在变量中存储相同类型的多个元素. 对于数组来说,最常见的就是迭代数组中的元素. 我们创建一个 Sum 函数,它使用 for 来循环获取数组中的元素并 ...

  4. Java面试——Spring Boot

    更多内容,移步IT-BLOG 一.谈谈你对 SpringBoot 的理解 简单说说我的理解:Java是一个静态语言,相比动态语言,它相对笨重,体现在我们搭建 SSM 框架写一个 Helloword 的 ...

  5. Windows无线连接路由器成功但无法网

    Windows10连接Wifi成功,任务栏无线图标没有感叹号,但是无法连接到网络,重启电脑才能连接上,手机连接这个网络却可以一直联通.本人使用的是intel 9260无线网卡,经过测试,我通过这个方法 ...

  6. jmeter关于常用取样器的设置

      常用创建操作   1.线程组:测试计划(右键)-->线程(用户)-->线程组   2.http请求:线程组(右键)-->取样器-->http请求   3.察看结果树:线程组 ...

  7. 学习docker看此文足以

    什么是 Docker Docker 最初是 dotCloud 公司创始人  在法国期间发起的一个公司内部项目,它是基于 dotCloud 公司多年云服务技术的一次革新,并于 ,主要项目代码在  上进行 ...

  8. Python集合常用操作

    一.集合的介绍   1.定义:集合是无序的,集合中的元素是唯一的,集合一般用于元组或者列表中的元素去重.   2.特性:集合的目的是将不同的值存放在一起,不同的集合间用来做关系运算,无须纠结于集合中的 ...

  9. pandas之loc/iloc操作

    在数据分析过程中,很多时候需要从数据表中提取出相应的数据,而这么做的前提是需要先"索引"出这一部分数据.虽然通过 Python 提供的索引操作符"[]"和属性操 ...

  10. [Linux]常用命令之【mount/umount】

    1 mount mount命令的作用是加载文件系统,它的用权限是超级用户或/etc/fstab中允许的使用者. 在Linux和Unix系统上,所有文件都是作为一个大型树(以/为根)的一部分访问的. 要 ...