Go 语言中 defer 使用时有哪些陷阱?
大家好,我是 frank ,「 Golang 语言开发栈」公众号作者。
01 介绍
defer 的使用方式是在其后紧跟一个函数调用或方法调用,确保在其所在的函数体返回之前执行其调用的函数或方法。
在 Go 语言中,defer 一般用于资源释放,或使用 defer 调用一个匿名函数,在匿名函数中使用 recover() 处理异常 panic。
在使用 defer 时,也很容易遇到陷阱,本文我们介绍使用 defer 时有哪些陷阱。
02 defer 陷阱
defer 语句不可以在 return 语句之后。
示例代码:
func main() {
name := GetUserName("phper")
fmt.Printf("name:%s\n", name)
if name != "gopher" {
return
}
defer fmt.Println("this is a defer call")
}
func GetUserName(name string) string {
return name
}
输出结果:
name:phper
阅读上面这段代码,我们在 return 语句之后执行 defer 语句,通过输出结果可以发现 defer 语句调用未执行。
虽然 defer 可以在函数体中的任意位置,我们也是需要特别注意使用 defer 的位置是否可以执行。
defer 语句执行匿名函数,参数预处理。
示例代码:
func main() {
var count int64
defer func(data int64) {
fmt.Println("defer:", data)
}(count + 1)
count = 100
fmt.Println("main:", count)
}
输出结果:
main: 100
defer: 1
阅读上面这段代码,首先我们定义一个类型为 int64 的变量 count,然后使用 defer 语句执行一个匿名函数,匿名函数传递参数为 count + 1,最终 main 函数输出 100,defer 执行的匿名函数输出 1。
因为在执行 defer 语句时,执行了 count + 1,并先将其存储,等到 defer 所在的函数体 main 执行完,再执行 defer 语句调用的匿名函数的函数体中的代码。
03 总结
本文主要介绍在使用 defer 语句时可能会遇到的陷阱。分别是 defer 语句不可以在 return 语句之后;defer 语句执行的匿名函数,匿名函数的参数会被预先处理。
读者朋友们在使用 Go 语言的 defer 语句时,还遇到过哪些陷阱?
Go 语言中 defer 使用时有哪些陷阱?的更多相关文章
- Go语言中defer语句使用小结
defer是Go语言中的延迟执行语句,用来添加函数结束时执行的代码,常用于释放某些已分配的资源.关闭数据库连接.断开socket连接.解锁一个加锁的资源.Go语言机制担保一定会执行defer语句中的代 ...
- C语言中的static 详细分析
转自:http://blog.csdn.net/keyeagle/article/details/6708077/ google了近三页的关于C语言中static的内容,发现可用的信息很少,要么长篇大 ...
- C语言中的static 具体分析
google了近三页的关于C语言中static的内容,发现可用的信息非常少,要么长篇大论不知所云要么在关键之处几个字略过,对于想挖掘底层原理的刚開始学习的人来说參考性不是非常大.所以,我这篇博文博採众 ...
- C语言中的static关键字
C语言代码是以文件为单位来组织的,在一个源程序的所有源文件中,一个外部变量(注意不是局部变量)或者函数只能在一个源程序中定义一次,如果有重复定义的话编译器就会报错.伴随着不同源文件变量和函数之间的相互 ...
- 【转载】C语言中的static 详细分析
原blog地址:http://blog.csdn.net/keyeagle/article/details/6708077/ google了近三页的关于C语言中static的内容,发现可用的信息很少, ...
- C语言中,头文件和源文件的关系(转)
简单的说其实要理解C文件与头文件(即.h)有什么不同之处,首先需要弄明白编译器的工作过程,一般说来编译器会做以下几个过程: 1.预处理阶段 2.词法与语法分析阶段 3.编译阶段,首先编译成纯汇编语句, ...
- C 语言中 setjmp 和 longjmp
在 C 语言中,我们不能使用 goto 语句来跳转到另一个函数中的某个 label 处:但提供了两个函数——setjmp 和 longjmp来完成这种类型的分支跳转.后面我们会看到这两个函数在处理异常 ...
- c语言中的scanf在java中应该怎么表达,Scanner类。
1 java是面向对象的语言 它没有像C语言中的scanf()函数,但是它的类库中有含有scanf功能的函数 2 java.util包下有Scanner类 Scanner类的功能与scanf类似 3 ...
- C语言中do...while(0)的妙用(转载)
转载来自:C语言中do...while(0)的妙用,感谢分享. 在linux内核代码中,经常看到do...while(0)的宏,do...while(0)有很多作用,下面举出几个: 1.避免goto语 ...
- C语言中,定义的含义?声明的含义?它们之间的区别是什么?
在C语言中,对于定义和声明,也许我们非常的熟悉,但不一定真正的了解! 定义的含义:所谓定义,就是创建(编译器)一个对象,为这个对象分配一块内存空间并取名,也就是我们平常所说的变量名或对象名,一旦这个名 ...
随机推荐
- spring报错
C:\Users\dell\.jdks\openjdk-19.0.2\bin\java.exe "-javaagent:E:\idea图片\IntelliJ IDEA 2022.2.3\li ...
- 34. 干货系列从零用Rust编写负载均衡及代理,异步测试在Rust中的实现
wmproxy wmproxy已用Rust实现http/https代理, socks5代理, 反向代理, 静态文件服务器,四层TCP/UDP转发,七层负载均衡,内网穿透,后续将实现websocket代 ...
- Mybatis-Flex之增、删、改
方法全解 (1) INSERT BaseMapper 的接口提供了 insert 和 insertBatch 方法,用于新增数据: insert(entity):插入实体类数据,不忽略 null 值. ...
- 7、If分支语句
1.程序的流程结构 程序的流程控制结构一共有三种: 顺序结构 选择结构 循环结构. 顺序结构: 从上向下 逐行执行 选择结构:条件满足,某些代码才会执行.0-1次 分支语句: if,switch,se ...
- HDU-2159 二维背包
最近xhd正在玩一款叫做FATE的游戏,为了得到极品装备,xhd在不停的杀怪做任务.久而久之xhd开始对杀怪产生的厌恶感,但又不得不通过杀怪来升完这最后一级.现在的问题是,xhd升掉最后一级还需n的经 ...
- scrapy 请求meta参数使用案例-豆瓣电影爬取
num = 0 import scrapy from scrapy.http import HtmlResponse from scrapy_demo.items import DoubanItem ...
- ElasticSearch之Index modules
索引的参数,分为两类: 静态参数,仅支持在创建索引时指定,或者关闭索引后指定. 动态参数,允许在索引工作期间指定或者修改. 静态参数 index.number_of_shards 默认值为1. 本参数 ...
- Python——第五章:json模块
什么是json: json 模块是用于处理 JSON(JavaScript Object Notation)数据的模块,翻译过来叫js对象简谱.JSON是一种轻量级的数据交换格式,常用于将数据在不同语 ...
- linux文件摘选
显示/var目录下所有以1开头,以一个小写字母结尾,且中间至少出现一位数字(可以由其他字符)的文件或目录. 命令: ls -d /var/1*[0-9]*[a-z] [root@foundation0 ...
- Salesforce LWC学习(四十六) record-picker组件浅谈
本篇参考: https://developer.salesforce.com/docs/platform/lwc/guide/reference-graphql.html https://develo ...