Go语言中defer语句使用小结
defer是Go语言中的延迟执行语句,用来添加函数结束时执行的代码,常用于释放某些已分配的资源、关闭数据库连接、断开socket连接、解锁一个加锁的资源。Go语言机制担保一定会执行defer语句中的代码。其它语言中也有类似的机制,比如Java、C#语言里的finally语句,C++语言里的析构函数(Destructor)可以起类似的作用,C++语言机制担保在对象被销毁前一定会执行析构函数中的代码。C++中的析构函数析构的是对象,Go中的defer析构的是函数。
一、defer语句执行时机
defer语句在函数返回之前 或者 函数中 return语句(return语句可能调用另一个函数) 之后执行。示例代码:
package main import (
"fmt"
) func main() {
fmt.Println(deferReturn())
} func deferReturn() (ret int) {
defer func() {
ret++
}()
return 10
}
上述代码打印出来的值是:11。 defer语句 匿名函数中的“ret++” 对返回值 10 加 1 变成了 11。再来看一个defer语句出现在return语句之后的代码:
func returnDefer() (ret int) {
return 0
defer func() {
ret++
ret++
}()
return 1
}
上述returnDefer函数的返回值是:0。原因是defer语句还没有添加上代码执行到"return 0"函数就返回了,因此defer语句就没有执行。
二、多个defer语句的执行顺序是逆序执行
当出现多条 defer 语句时以逆序执行(类似栈,即后进先出)。示例代码:
func deferSample() {
for i := 0; i < 5; i++ {
defer fmt.Printf("%d ", i)
}
}
上述代码将会输出:4 3 2 1 0
三、defer与panic
1、在panic语句后面的defer语句不被执行
示例代码:
func panicDefer() {
panic("panic")
defer fmt.Println("defer after panic")
}
上述代码的输出如下:
panic: panic
goroutine 1 [running]:
main.panicDefer()
E:/godemo/testdefer.go:17 +0x39
main.main()
E:/godemo/testdefer.go:13 +0x20
Process finished with exit code 2
可以看到 defer 语句没有执行。
2、在panic语句前的defer语句会被执行
示例代码:
func deferPanic() {
defer fmt.Println("defer before panic")
panic("panic")
}
上述代码的输出如下:
defer before panic
panic: panic
goroutine 1 [running]:
main.deferPanic()
E:/godemo/testdefer.go:19 +0x95
main.main()
E:/godemo/testdefer.go:14 +0x20
Process finished with exit code 2
defer 语句输出了内容。
Go中的panic类似其它语言中的抛出异常,panic后面的代码不再执行(panic语句前面的defer语句会被执行)。
四、return 的实现逻辑
1、第一步给返回值赋值(若是有名返回值直接赋值,匿名返回值 则 先声明再 赋值) ;
2、第二步调用RET返回指令并传入返回值,RET会检查是否存在defer语句,若存 在就先逆序插播 defer语句 ;
3、最后 RET 携带返回值退出函数 。
可以看出 , return 不是一个原子操作,函数返回值与 RET 返回值并不一定一致。
五、defer、 return、返回值三者顺序
defer、 return、返回值 三者的执行顺序是 : return 最先给返回值赋值;接着 defer 开始执行一些收尾工作;最后 RET 指令携带返回值退出函数。
Go语言中defer语句使用小结的更多相关文章
- C语言中if语句
C语言if语句后面的表达式 C语言中if关键字之后(即括号内)均为表达式. 该表达式通常是逻辑表达式或关系表达式,但也可以是其它表达式,如赋值表达式等,甚至也可以是一个变量,这些变量的值都换算成了逻辑 ...
- C语言中while语句里使用scanf的技巧
今天友人和我讨论了一段代码,是HDU的OJ上一道题目的解,代码如下 #include<stdio.h> { int a,b; while(~scanf("%d%d",& ...
- C语言中while 语句
while的执行顺序 while 循环的执行顺序非常简单,它的格式是: while (表达式) { 语句: } 概念:当表达式为真,则执行下面的语句:语句执行完之后再判断表达式是否为真,如果为真,再次 ...
- c语言中的switch case语句
switch--case语句中,switch后面跟一个变量,这个变量不可以是字符数组,字符指针,字符串数组,浮点型(实型).它可以是整型,字符型(在本质上也是整型).所以这导致case后面的常量表达式 ...
- Go语言中的defer
可以用作一些资源的释放. 1.在一个函数内的defer执行顺序是先写的后执行,后写的先执行(遵循栈结构) func DeferTest1(){ defer fmt.Println("我是 d ...
- C/C++语言中const的用法
1. const 在C和C++中的区别 C++中的const正常情况下是看成编译期的常量,编译器并不为const分配空间,只是在编译的时候将期值保存在名字表中,并在适当的时候折合在代码中. 所 ...
- golang学习 ---defer语句
golang语言defer特性详解 defer语句是go语言提供的一种用于注册延迟调用的机制,它可以让函数在当前函数执行完毕后执行,是go语言中一种很有用的特性.由于它使用起来简单又方便,所以深得go ...
- C语言中,头文件和源文件的关系(转)
简单的说其实要理解C文件与头文件(即.h)有什么不同之处,首先需要弄明白编译器的工作过程,一般说来编译器会做以下几个过程: 1.预处理阶段 2.词法与语法分析阶段 3.编译阶段,首先编译成纯汇编语句, ...
- C 语言中 setjmp 和 longjmp
在 C 语言中,我们不能使用 goto 语句来跳转到另一个函数中的某个 label 处:但提供了两个函数——setjmp 和 longjmp来完成这种类型的分支跳转.后面我们会看到这两个函数在处理异常 ...
随机推荐
- 【安卓基础】WebView开发优化基础
最近工作很忙,不仅要抽空进行管理,还有开发任务在身,幸好有一些规划进行指导,所以还能顺利解决问题.在管理和技术上面,我认为技术是硬实力,管理是软实力,自己需要多点时间花在技术上. 回归正题,在项目中的 ...
- STL练习板子题(c++11警告)
第一题 词典 总时间限制: 3000ms 内存限制: 65536kB 描述 你旅游到了一个国外的城市.那里的人们说的外国语言你不能理解.不过幸运的是,你有一本词典可以帮助你. 输入 首先输入一个词典, ...
- ckeditor粘贴word文档图片的思路
由于工作需要必须将word文档内容粘贴到编辑器中使用 但发现word中的图片粘贴后变成了file:///xxxx.jpg这种内容,如果上传到服务器后其他人也访问不了,网上找了很多编辑器发现没有一个能直 ...
- leetcode解题报告(6):Remove Duplicates from Sorted List
描述 Given a sorted linked list, delete all duplicates such that each element appear only once. For ex ...
- Java操作文件那点事
刚开始学Java时候,一直搞不懂Java里面的io关系,在网上找了很多大多都是给个结构图草草描述也看的不是很懂.而且没有结合到java7 的最新技术,所以自己结合API来整理一下,有错的话请指正,也希 ...
- Irrlicht引擎剖析二
- final关键字的理解
final :最终作为一个修饰符 1.可以修饰类,函数,变量: 2.被final修饰的类不可以被继承: 3.被final修饰的方法不可以被复写: 4.被final修饰的变量是一个常量,只能赋值一次,既 ...
- Maven的概述和基础(学习整理)
1. Maven是啥 Maven是一个项目管理工具,包含了一个项目对象模型(POM),一组标准集合,一个项目生命周期(Lifecycle),一个依赖管理系统,和用来运行定义在生命周期阶段中的插件目标的 ...
- 学号20175313 《实现Linux下Sort -t : -k 2功能》第十二周
目录 一.题目要求 二.题目理解 三.设计思路 四.代码实现 五.代码链接 六.运行结果截图 七.参考资料 一.题目要求 实现Linux下Sort -t : -k 2的功能 二.题目理解 -t 分隔符 ...
- NMS(非极大值抑制)实现
1.IOU计算 设两个边界框分别为A,B.A的坐标为Ax1,Ax2,Ay1,Ay2,且Ax1 < Ax2,Ay1 < Ay2.B和A类似. 则IOU为A∩B除以A∪B. 当两个边界框有重叠 ...