千家信息网

Go语言中defer的示例分析

发表于:2024-12-12 作者:千家信息网编辑
千家信息网最后更新 2024年12月12日,本篇文章为大家展示了Go语言中defer的示例分析,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。Go语言中的defer机制。今天我们来看一段defer 机制代
千家信息网最后更新 2024年12月12日Go语言中defer的示例分析

本篇文章为大家展示了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的示例分析,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注行业资讯频道。

0