Golang defer使用
学习于https://www.liwenzhou.com/posts/Go/function/的文章
1. defer的执行顺序类似于栈,“后进先出”,也就是最先defer的语句最后执行,而最后defer的最先执行
func main() {
defer fmt.Println("1")
defer fmt.Println("2")
defer fmt.Println("3")
}
//控制台打印
3
2
1
2. defer和return的坑
首先return操作并不是原子操作,他分为2步:一是给返回值赋值,二是return返回值。如果函数中有defer的话,那么defer会被夹杂在2步中间,也就是先给返回值赋值,执行defer,return返回值。
func main() {
fmt.Println("匿名返回:", a()) //5
fmt.Println("有名返回:", b()) //6
}
// 匿名返回值
func a() int {
x := 5
defer func() {
x++
}()
return x
}
// 有名返回值
func b() (x int) {
x = 5
defer func() {
x++
}()
return x
}
使用匿名返回函数,控制台打印的是5,这是执行return x时,首先定义 返回值=x(非同一个变量),然后执行defer x++,最后return返回值,而此时返回值已经=x,x++不会再影响返回值了,所以返回的是5。
使用有名返回时,就指定了返回值=x(同一个变量,内存地址相同),所以x++后,返回的值也++了。
3. defer注册要延迟执行的函数时该函数所有的参数都需要确定其值
func calc(index string, a, b int) int {
ret := a + b
fmt.Println(index, a, b, ret)
return ret
}
func main() {
x := 1
y := 2
defer calc("AA", x, calc("A", x, y))
x = 10
defer calc("BB", x, calc("B", x, y))
y = 20
}
第一次注册defer calc("AA", x, calc("A", x, y))时,会执行里面的calc("A", x, y),此时x=1,y=2,所以先打印,
A 1 2 3
于是defer calc("AA", x, calc("A", x, y))中的参数被确定,是defer calc("AA", 1, 3)
接下来x=10,y没变,仍等于2,执行defer calc("BB", x, calc("B", x, y)),执行calc("B", x, y),打印
B 10 2 12
于是defer calc("BB", x, calc("B", x, y))中的参数被确定,是defer calc("BB", 10, 12)
然后按照defer顺序执行,先执行defer calc("BB", 10, 12),再执行defer calc("AA", 1, 3),所以打印
BB 10 12 22
AA 1 3 4
Golang defer使用的更多相关文章
- golang defer 延后执行什么
对于golang的defer,我们已经知道,defer定义的语句可以延后到函数返回时执行. 经常用在文件的关闭,锁的释放等场景中.而且defer定义的语句即使遇到panic也会执行.这样,可以执行必要 ...
- golang defer的使用
defer一般用于在函数结束时执行必要的处理工作.例如,关闭文件描述符,关闭网络连接等等. 函数中可以定义多个defer,执行的时候按照先进后出的顺序. defer定义的语句,即使遇到panic,也会 ...
- 拒绝滥用golang defer机制
原文链接 : http://www.bugclosed.com/post/17 defer机制 go语言中的defer提供了在函数返回前执行操作的机制,在需要资源回收的场景非常方便易用(比如文件关闭, ...
- golang defer使用——资源关闭时候多用
defer Go语言中有种不错的设计,即延迟(defer)语句,你可以在函数中添加多个defer语句.当函数执行到最后时,这些defer语句会按照逆序执行,最后该函数返回.特别是当你在进行一些打开资源 ...
- golang defer那些坑
defer以下几个特性,使用时需要关注下. 即时的参数传递 调用os.Exit()时defer不会被执行 defer与return的先后顺序 1.即时的参数传递 定义defer时传入的参数,是作为拷贝 ...
- golang defer 以及 函数栈和return
defer 作为延迟函数存在,在函数执行结束时才会正式执行,一般用于资源释放等操作 参考一段代码https://mp.weixin.qq.com/s/yfH0CBnUBmH0oxfC2evKBA来分析 ...
- Golang入门教程(十三)延迟函数defer详解
前言 大家都知道go语言的defer功能很强大,对于资源管理非常方便,但是如果没用好,也会有陷阱哦.Go 语言中延迟函数 defer 充当着 try...catch 的重任,使用起来也非常简便,然而在 ...
- 探究 Go 语言 defer 语句的三种机制
Golang 的 1.13 版本 与 1.14 版本对 defer 进行了两次优化,使得 defer 的性能开销在大部分场景下都得到大幅降低,其中到底经历了什么原理? 这是因为这两个版本对 defer ...
- 【GoLang】panic defer recover 深入理解
唉,只能说C程序员可以接受go的错误设计,相比java来说这个设计真的很差劲! 我认为知乎上说的比较中肯的: 1. The key lesson, however, is that errors ar ...
- golang中defer的使用规则
转自个人博客chinazt.cc 在golang当中,defer代码块会在函数调用链表中增加一个函数调用.这个函数调用不是普通的函数调用,而是会在函数正常返回,也就是return之后添加一个函数调用. ...
随机推荐
- Matlab字体设置中找不到字体的解决方法(转载)
Matlab字体设置中找不到字体 Matlab默认的字体实在不好看,一般都需要重新设置字体. 在其字体设置中有些字体不能同时支持中文和英文,我在之前的博客中说过,如何为Matlab设置一款好看的同时兼 ...
- 1011.Django状态保持以及表单
一.session保持状态 状态保持: 1. http协议是无状态的:每次请求都是一次新的请求,不会记得之前通信的状态: 2. 客户端与服务器端的一次通信,就是一次会话实现状态保持的方式:在客户端或服 ...
- vim用法思维导图
- MQ(部署模式)
MQ部署模式 1.master-slave部署模式 1)shared filesystem Master-Slave部署方式 主要是通过共享存储目录来实现master和slave的热备,所有的Acti ...
- mitmproxy截取流量和抓包
mitmproxy介绍https://blog.csdn.net/enemy_sprites/article/details/104052506 mitmproxy处理请求及乱码https://blo ...
- GO语言学习笔记-方法篇 Study for Go ! Chapter five - Method
持续更新 Go 语言学习进度中 ...... GO语言学习笔记-类型篇 Study for Go! Chapter one - Type - slowlydance2me - 博客园 (cnblogs ...
- SpringBoot笔记--自动配置(高级内容)(中集)
@Enable*注解 使用该注解,需要导入相应的依赖坐标,其中的groupId标签里面写入Bean的Java文件所在的包的路径下面 spring-enable-other 还需要在SpringBoot ...
- Android笔记--Android studio里面打开数据库详解
1.下载Database Navigator插件,然后需要重启Android studio 2.然后会总界面这里.出现这样一个图标 然后选中Database Brower: 3.弹出这样一个界面 然后 ...
- MySQL学习(三)DQL/DML/DDL/DCL 介绍
参考博客:https://blog.csdn.net/tomatofly/article/details/5949070 DQL(data query language) :数据查询语言 select ...
- 最近写了一个demo,想看看java和go语言是怎么写的
最近写了一个demo:demo的github地址 一. 简单介绍 1. Server端 它是一个WebApi服务,把它当成一个黑盒就行了. 2. MiddleServer端 是重点,它是一个WebAp ...