Go语言 defer问题详解

一、defer是什么

1、概念

defer是Golang中的一个关键字,简单用法:defer <函数func>

2、功能

用来声明其后的函数为延迟函数,可以定义多个延时函数,这些函数会放入到一个栈中,当函数执行 到最后时,这些defer语句会按照逆序执行,最后该函数返回。(具体栈结构见下文)
通常用defer来做一些资源的释放,比如关闭io操作。

二、defer数据结构

type _defer struct {
   
    sp      uintptr   //函数栈指针
    pc      uintptr   //程序计数器
    fn      *funcval  //函数地址
    link    *_defer   //指向自身结构的指针,用于链接多个defer
}

由于defer后接一个函数,所以defer的数据结构跟一般函数类似,也有栈指针、程序计数器、函数地址等等。与函数不同的是它含有一个指针,可用于指向另一个defer,每个goroutine数据结构中实际上也有一个defer指针,该指针指向一个defer的链表,每次声明一个defer时就将defer插入到单链表表头,每次执行defer就从单链表表头取出一个defer执行。

如图所示:
Go语言 defer问题详解_第1张图片

新声明的defer B()总是添加到链表头部,函数返回前执行defer则是从链表首部依次取出执行,形成一个栈结构。

三、defer使用的重点

以下内容部分来自: https://learnku.com/articles/42255#7fa787

1、defer 的执行顺序

一个函数中使用多个defer时,它们是一个 “栈” 的关系,也就是先进后出,先在后面的defer先执行。

func main() {
   
   defer func1()
   defer func2()
   defer func3()
}
func func1() {
   
   fmt.Print("A")
}
func func2() {
   
   fmt.Print("B")
}
func func3() {
   
   fmt.Print("C")
}

Go语言 defer问题详解_第2张图片

执行输出为:C B A

2、defer 与 return 谁先谁后

根据代码运行情况可以理解为:return 之后的语句先执行,defer 后的语句后执行。不过,defer执行时是可以改变return中的返回值的。

3、当defer被声明时,其参数就会被实时解析

func a(

你可能感兴趣的:(golang,链表,数据结构)