Golang中的defer关键字的用法、原理以及它的坑

延迟函数调用(deferred function call)是golang中很有特点的一个功能,通过defer修饰的函数调用会在函数退出的时候才被真正调用,它可以用来进行资源释放等收尾工作。
一个普通的函数调用被defer关键字修饰以后,就构成了一个延迟函数调用,和协程调用类似,被延迟的函数调用的所有返回值都会全部被舍弃。

延迟函数调用的用法

首先我们看看延迟函数调用的用法,它的用法其实很简单!
简单是示例代码:

func main(){
   
  defer func() {
    fmt.Println("延迟调用") }()
  fmt.Println("正常调用")
}

代码执行结果:

正常代码
延迟调用

从结果我们可以很直观的发现,被defer修饰的函数调用在后面执行了,也就是被延迟调用了。

多个延迟函数调用的执行顺序

上面的示例代码很简单,输出结果也很好理解,接下来我们看一个稍微复杂一丢丢的代码:

func main(){
   
	defer func() {
    fmt.Println("延迟调用1") }()
	defer func() {
    fmt.Println("延迟调用2") }()
	fmt.Println("正常代码")
}

这段代码和之前的代码唯一的不同之处是多了一个被defer修饰的函数调用,那么这小段代码的输出又会是什么样的呢?
是先输出[延迟调用1]还是先输出[延迟调用2]呢?跑一下程序自然就知道啦!
代码执行结果:

正常代码
延迟调用2
延迟调用1

[延迟调用2]被先输出了,这是为什么呢?
这是因为每一个协程都会维护一个延迟调用堆栈,按照代码顺序把需要延迟调用的函数压入栈中,当函数进入退出阶段后,就会从延迟调用堆栈中取出需要执行的函数调用并执行。

延迟函数调用的实现原理

上面讲了基本的用法,接下来我们再深入到golang源码看看defer关键字是如何实现的。为了便于分析,我用下面的代码进行分析:

func main(){
   
	defer func() {
   }()
	defer func() {<
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值