温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Go语言中defer的示例分析

发布时间:2021-12-27 13:50:44 来源:亿速云 阅读:130 作者:柒染 栏目:互联网科技

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

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI