流程控制:defer延迟执行

延迟调用

defer是Go语言中的延迟执行语句。

用来添加函数结束时执行的代码,常用于释放某些已分配的资源、关闭数据库连接、断开socket连接、解锁一个加锁的资源。

  • Go语言机制担保一定会执行defer语句中的代码

  • 其它语言中也有类似的机制,比如Java、C#语言里的finally语句

  • defer 的用法很简单,只要在后面跟一个函数的调用,就能实现将这个xxx函数的调用,延迟到当前函数执行完后再执行。

如下示例

import "fmt"

func myfunc() {
    fmt.Println("B")
}

func main() {
    defer myfunc()
    fmt.Println("A")
}

输出如下

defer特性

defer用途:

即时求值的变量快照

使用 defer 只是延时调用函数,此时传递给函数里的变量,不受到后续程序的影响

比如下面的例子

输出如下

多个defer 反序调用

当在一个函数里使用了 多个defer,那么这些defer 的执行函数是如何的呢? 如下示例:

输出如下:

可见 ,多个defer 是反序调用的,类似栈一样,后进先出

defer 与 return 孰先孰后

代码示例:

输出如下

来一起理解一下这段代码,第一行很直观,name 此时还是全局变量,值还是go

第二行也不难理解,在 defer 里改变了这个全局变量,此时name的值已经变成了 python

重点在第三行,为什么输出的是 go ?

原因是defer 是return 后才调用的。所以在执行 defer 前,myname 已经被赋值成 go 了。 结论: defer 与 return 孰先孰后?return先执行,defer后执行

return 的实现逻辑

1、第一步给返回值赋值(若是有名返回值直接赋值,匿名返回值 则 先声明再 赋值) ; 2、第二步调用RET返回指令并传入返回值,RET会检查是否存在defer语句,若存 在就先逆序插播 defer语句 ; 3、最后 RET 携带返回值退出函数 。

defer、 return、返回值三者顺序

defer、 return、返回值 三者的执行顺序是 : return 最先给返回值赋值;接着 defer 开始执行一些收尾工作;最后 RET 指令携带返回值退出函数

为什么要有 defer

用来添加函数结束时执行的代码,常用于释放某些已分配的资源、关闭数据库连接、断开socket连接、解锁一个加锁的资源

若是没有 defer,你可以写出这样的代码

使用了 defer 后,代码就显得简单直接,不管你在何处 return,都会执行 defer 后的函数。

defer 是先进后出

这个很自然,后面的语句会依赖前面的资源,因此如果先前面的资源先释放了,后面的语句就没法执行了。go

Last updated