Go 延迟调用机制

  defer延迟调用机制

是什么?为什么?

延迟调用是函数return正常结束后或者painc异常结束前会执行的一些操作。

再申请资源的时候延迟调用,防止忘记资源释放,数据库、文件、锁等资源释放。

延迟调用的顺序?

会按先进后出的顺序执行。

defer的值什么时候传递的?对外部变量如何引用?

defer定义时值就传递给defer了。

defer定义时对外部变量引用有两种方式:函数参数、闭包引用  

func main() {n := 3defer fmt.Println(n)n = 5
}
type number intfunc (n number) print()   { fmt.Println(n) }
func (n *number) pprint() { fmt.Println(*n) }
func main() {var n numberdefer n.print()n = 3
}/*defer n.print()defer n.pprint()defer func() { n.print() }()defer func() { n.pprint() }()
*/

defer_使用

func main() {defer fmt.Println("函数退出前执行")
}

defer_特性多个defer的执行顺序

func main() {defer fmt.Println("顺序 1")defer fmt.Println("顺序 2")defer fmt.Println("顺序 3")
}//结果
/*
顺序 3
顺序 2
顺序 1*/

 defer_return xxx 的注意事项

执行顺序
return ***
defer
return 

func f() int {r := 5defer func() { r += 5 }()return r
}
func main() {fmt.Println(f())
}

func f() (r int) {t := 5defer func() { t += 5 }()return t
}
func main() {fmt.Println(f())
}
func f() (r int) {r = 5defer func() { r += 5 }()return
}
func main() {fmt.Println(f())
}

defer_应用释放资源

打开文件

func main() {file, err := os.Open("example.txt") //打开文件if err != nil {fmt.Println("Error opening file:", err)return}defer file.Close() // 在函数结束前确保文件被关闭//对文件的操作//...// 这里不需要显式关闭文件,defer 会在函数结束时调用 file.Close()
}

http请求

func main() {// 发起 HTTP GET 请求resp, err := http.Get("https://jsonplaceholder.typicode.com/posts/1")if err != nil {fmt.Println("Error fetching data:", err)return}defer resp.Body.Close() // 确保在函数结束时关闭 HTTP 响应体// 读取响应的内容body, err := ioutil.ReadAll(resp.Body)if err != nil {fmt.Println("Error reading response body:", err)return}fmt.Println("Response:", string(body))
}

defer_应用事务回滚

func performDatabaseOperation() error {db, err := sql.Open("mysql", "username:password@tcp(localhost:3306)/dbname")if err != nil {return err}defer db.Close() // 确保在函数结束时关闭数据库连接// 开始数据库事务tx, err := db.Begin()if err != nil {return err}defer func() {if p := recover(); p != nil {fmt.Println("Recovering from panic:", p)tx.Rollback() // 如果出现 panic,回滚事务panic(p)      // 继续传播 panic}}()// 在事务中执行一些操作_, err = tx.Exec("INSERT INTO table_name (column_name) VALUES (?)", "some value")if err != nil {tx.Rollback() // 发生错误时回滚事务return err}// 在函数结束时提交事务defer tx.Commit()// 模拟某些可能触发 panic 的操作// panic("something went wrong")return nil
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/847706.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

景源畅信电商:抖音小店怎么做好运营?

在如今这个数字化时代,电商平台如雨后春笋般涌现,其中抖音小店以其独特的短视频营销模式迅速崛起。如何在这个竞争激烈的市场中占据一席之地,成为了许多商家和创业者思考的问题。下面,我们将深入探讨抖音小店的运营策略&#xff0…

多线程插入10万条数据,且避免堆栈溢出

在多线程环境下插入大量数据(如10万条)时,避免堆栈溢出的关键在于合理管理线程的生命周期、控制递归深度(如果使用了递归的话),以及合理分配每个线程处理的数据量。以下是一些建议来实现这个目标&#xff1…

论文阅读[268]基于EEM荧光光谱,感知燃烧产生的颗粒物

【论文基本信息】 标题:EEM Fluorescence Spectroscopy based Sensing of Combustion Generated Particulate Matter 来源与类型:华盛顿大学,博士学位论文 推荐理由:论文作者将主成分回归(PCR)方法与三维荧光光谱结合,预测样本中特定类污染物的总浓度,准确率达到了97.6…

Qt——控件

目录 概念 QWidget核心属性 enabled geometry WindowFrame的影响 windowTitle windowIcon qrc的使用 windowOpacity cursor font toolTip focusPolicy ​编辑 styleSheet 按钮类控件 PushButton RadioButton CheckBox 显示类控件 Label textFormat pixm…

docker run 两个挂载路径怎么设置

docker run 两个挂载路径怎么设置 在使用 docker run 命令时,如果需要挂载多个宿主机目录到容器中,您只需为每个挂载路径添加一个 -v 或 --volume 选项即可。下面是一个示例,展示了如何挂载两个宿主机目录到容器的不同路径上: Bas…

MongoDB CRUD操作:地理位置应用——通过地理空间查询查找餐厅

MongoDB CRUD操作:地理位置应用——通过地理空间查询查找餐厅 文章目录 MongoDB CRUD操作:地理位置应用——通过地理空间查询查找餐厅地图的扭曲搜索餐厅浏览数据查找当前邻居查找附近所有餐厅查找一定距离内的餐厅使用$geoWithin,不排序使用…

redhat遇到安装包缺失问题

缺失的文件用repoquery --nvr --whatprovides XXX 查询 repoquery --nvr --whatprovides libstdc.so.6然后使用yum -y install XXX 选择查询到的文件的安装 yum -y install libstdc-8.5.0-3.el8Last metadata expiration check: 0:06:30 ago on Wed Jun 5 04:02:24 2024. lib…

模板进阶

非类型模板参数(常量参数) 相当于向类传递常量(编译前确定)参数 只能传整型/size_t,不可double等 C20 后可以支持其他内置类型(可指针) 自定义类型的实参永远不行 array 可理解为固定size的…

JS继承的方式

目录 原型链继承构造函数继承组合继承寄生组合继承ES6 Class 继承原型链继承 原理: 通过将子类的原型(prototype)设置为父类的一个实例,使得子类实例能够沿着原型链访问到父类的属性和方法。 function Parent() {this.parentProperty

在点云地图中进行点云计数

文章目录 概要头文件主要代码概要 在激光SLAM(Simultaneous Localization and Mapping)中,局部点云地图是通过激光雷达扫描捕捉到的周围环境的局部三维点集合。统计局部点云地图中的所有点数目是一个常见的需求,这可以帮助我们了解数据的密集程度、有效性等。 为了统计局…

JavaEE:http请求 | 过滤器 | 同步与异步请求 | 跨域问题 | axios框架 有这一篇就够!

📃HTTP请求 ▐ http超文本传输协议: ⦁ http超文本传输协议属于应用层协议,传输内容必须是超文本内容 (网页内容) ⦁ 例如在网页上点击超链接,提交表单,都可以向后端发送一个http请求 ⦁ 一次http请求中包含请求行、…

力扣167. 两数之和 II - 输入有序数组

Problem: 167. 两数之和 II - 输入有序数组 文章目录 题目描述思路复杂度Code 题目描述 思路 1.定义左、右指针left、right分别指向数组索引为0和索引为nums.length - 1,定义结果数组int[] res new int[2]用于存储索引; 2.查找:当判断numbers[left] nu…

机器视觉——硬件常用基础知识

光源 机器视觉中光源的作用 1)强化特征,弱化背景 2)光源打得好,图好了,后期算法更简化 3)图好了,测试速度更高 各种光源的综合性能对比及为啥使用LED灯 光的颜色的选择 白色光:通常用…

Qwen-VL论文阅读

论文地址 其他同学的详细讲解 模型结构和参数大小 (1)LLM:Qwen-7B (2)Vision Encoder:ViT架构,初始化参数是 Openclip’s ViT-bigG。 在训练和推理过程中,输入的图像都被调整到…

C语言函数递归实现汉诺塔问题

汉诺塔问题的大概 汉诺塔问题如图三个柱子,利用B将A上面的盘子移到C上面,但是一次只能移动一个盘子并且大的盘子不可以在小的盘子上面。 当只有三个盘子的时候,就像图片一样移动,当盘子多了起来我们就很难分得清逻辑了。 这个时候…

MySQL之查询性能优化(四)

查询性能优化 MySQL客户端/服务器通信协议 一般来说,不需要去理解MySQL通信协议的内部实现细节,只需要大致理解通信协议是如何工作的。MySQL客户端和服务器之间的通信协议是"半双工"的,这意味着,在任何一个时刻&#…

【退役之重学】为什么要加入多级缓存

一、为什么 加入多级缓存是为了提高数据访问的效率和性能 二、怎么做 在多级访问系统中,数据首先会被存储在速度最快的 L1 缓存中,如果数据在 L1 缓存中未命中,则会继续在 L2 缓存 和 L3 缓存中查找,如果在所有缓存中都未命中&…

java —— 打印流

打印流分字符打印流 PrintWriter 和字节打印流 PrintStream,两者用法基本一样,但字符打印流明显应用范围更广一些。 一、打印至控制台 public static void main(String[] args) {String str"hello";PrintWriter pwnew PrintWriter(System.ou…

神经网络与深度学习——第15章 序列生成模型

本文讨论的内容参考自《神经网络与深度学习》https://nndl.github.io/ 第15章 序列生成模型,习题还没做先存在这里。 序列生成模型 序列概率模型 序列生成 N元统计模型 深度序列模型 模型结构 嵌入层 特征层 输出层 参数学习 评价方法 困惑度 BLEU算法 ROUGE算法 序…

redhat8安装cadence遇到的问题

问题1 virtuoso: ERROR: The OA2.2 library directory (/cadence/IC618/share/oa/lib/linux_rhel50_gcc48x_64/opt) does not seem to exist. virtuoso: INFO: You have OA_UNSUPPORTED_PLAT set to "linux_rhel50_gcc48x" in your environment: virtuoso: …