2022-10-29:go语言中的defer能非常方便地处理资源释放问题,rust语言里如何实现defer功能呢?
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功能呢?的更多相关文章
- C语言中string char int类型转换
C语言中string -- ::) 转载 ▼ 标签: 操作符 int char c语言 类型转换 分类: C/Cpp ,char型数字转换为int型 "; printf(]-');//输出结 ...
- Go语言中的defer
可以用作一些资源的释放. 1.在一个函数内的defer执行顺序是先写的后执行,后写的先执行(遵循栈结构) func DeferTest1(){ defer fmt.Println("我是 d ...
- Go语言中defer语句使用小结
defer是Go语言中的延迟执行语句,用来添加函数结束时执行的代码,常用于释放某些已分配的资源.关闭数据库连接.断开socket连接.解锁一个加锁的资源.Go语言机制担保一定会执行defer语句中的代 ...
- C语言中do...while(0)的妙用(转载)
转载来自:C语言中do...while(0)的妙用,感谢分享. 在linux内核代码中,经常看到do...while(0)的宏,do...while(0)有很多作用,下面举出几个: 1.避免goto语 ...
- 在不同语言中static的用法
static (计算机高级语言) 编辑 像在VB,C#,C,C++,Java,PHP中我们可以看到static作为关键字和函数出现,在其他的高级计算机语言如FORTRAN.ALGOL.COBOL.BA ...
- C语言中setjmp与longjmp学习笔记
C语言中setjmp与longjmp学习笔记 一.基础介绍 头文件:#include<setjmp.h> 原型: int setjmp(jmp_buf envbuf) ,然而longjm ...
- C语言中,头文件和源文件的关系(转)
简单的说其实要理解C文件与头文件(即.h)有什么不同之处,首先需要弄明白编译器的工作过程,一般说来编译器会做以下几个过程: 1.预处理阶段 2.词法与语法分析阶段 3.编译阶段,首先编译成纯汇编语句, ...
- 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 ...
- 转:C语言中的static变量和C++静态数据成员(static member)
转自:C语言中的static变量和C++静态数据成员(static member) C语言中static的变量:1).static局部变量 a.静态局部变量在函数内定义,生存期为整个程序 ...
- C语言中.h和.c文件解析(很精彩)
C语言中.h和.c文件解析(很精彩) 简单的说其实要理解C文件与头文件(即.h)有什么不同之处,首先需要弄明白编译器的工作过程,一般说来编译器会做以下几个过程: 1.预处理阶段 2.词法与语法分析 ...
随机推荐
- freopen函数
C/C++ 输入输出到文件 freopen("in.txt","r",stdin); freopen("out.txt","w&q ...
- MySQL 分组排序,取第一条
select t1.* from coal_installed_capacity t1where NOT EXISTS (select * from coal_installed_capacity t ...
- 定制centos发行版
//轻量级Centos定制发行版==================================================================================== ...
- java 程序运行机制
java 程序运行同时拥有 编译型语言和解释型语言的特点 程序运行流程: 源程序 .java文件 --> Java 编译器--> 字节码 .class 文件 --> 类装饰器 --& ...
- JAVA加载PMML算法模型
注:加载失败时尝试修改pmml文件版本为4.3 依赖 <dependency> <groupId>org.jpmml</groupId> <artifactI ...
- 理解Map-构建关联数组
理解Map 要更深入理解map,学习如何构建关联数组是很有帮助的,以下是简单实现 package org.example.onjava.senior.example03collection.map; ...
- Axios的js文件的下载教程+相关应用
下载教程来啦! 1.进入GitHub网站,网址在这里:http://github.com 2.去搜索框搜索Axios,得到如下界面: 3.然后选择这里: 会出现如下界面: 4.点击右方的绿色按钮&qu ...
- SpringBoot 整合 Kafka 与 Avro 【No group.id】 问题解决方法
[问题描述]:ApplicationContextException: Failed to start bean 'org.springframework.kafka.config.internalK ...
- new做了哪些事情,手写一个new
1)创建一个空对象,将构造函数中的this指向这个空对象 2)将空对象的__proto__指向构造函数的prototype原型 3)执行构造函数里面的代码,为这个空对象添加属性和方法 4)返回一个新的 ...
- 机器学习算法(九): 基于线性判别模型的LDA手写数字分类识别
1.机器学习算法(九): 基于线性判别模型的LDA手写数字分类识别 1.1 LDA算法简介和应用 线性判别模型(LDA)在模式识别领域(比如人脸识别等图形图像识别领域)中有非常广泛的应用.LDA是一种 ...