本篇文章为大家展示了Go语言中defer的示例分析,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。
Go语言中的defer机制。
今天我们来看一段defer 机制代码:
func calc(index string, a, b int) int {
ret := a + b
fmt.Println(index, a, b, ret)
return ret
}
func main() {
a := 1
b := 2
defer calc("1", a, calc("10", a, b))
a = 0
defer calc("2", a, calc("20", a, b))
b = 1
}
那么你觉得这段代码的正确输出是什么呢?
我们知道的defer是按照FILO(Fisrt In Last Out)的原则进行调用的。我们按照这个规则分析可能会得出下面的结果:
20 0 2 2
2 0 2 2
10 1 2 3
1 1 3 4
但是当我们运行的时候,结果其实是下面这个:
10 1 2 3
20 0 2 2
2 0 2 2
1 1 3 4
怎么会这样呢?这就要说到官方对defer的解释了。
defer语句将函数调用推送到列表上。保存的调用列表在周围函数返回后执行。Defer通常用于简化执行各种清理操作的函数。
官方说的是会在包含defer的函数“返回”时,调用defer列表(满足FILO)。但是官方的这个并没有说清楚怎么调用。而现实情况是,defer在使用时会保存当前的所有变量,如果遇到这种变量中有函数的,会先进行函数调用得到值,然后保存下来。
defer实际步骤如下:
1. 在defer表达式的地方,会调用runtime.deferproc(size int32, fn *funcval)保存延时调用,注意这里保存了延时调用的参数
2. 在return时,先将返回值保存起来
3. 按FILO顺序调用runtime.deferreturn,即延时调用
4. RET指令
所以在本文中执行到第一个defer时,会先计算所有的参数,并压入栈。然后到第二个defer时,再计算所有的参数,再压入栈。最后在return的时候依次把第二个的defer和第一个defer弹出。最终就是我们看到的结果。
上述内容就是Go语言中defer的示例分析,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注亿速云行业资讯频道。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。