美文网首页
go 的 defer 实现原理

go 的 defer 实现原理

作者: wayyyy | 来源:发表于2022-08-30 00:25 被阅读0次
defer 需要注意的2点
  • defer 函数的参数在defer 语句出现时就已经确定

    func foo() {
        i := 0
        defer fmt.Println(i)
        i++
        return
    }
    

    输出 i 的值为0

  • defer 函数可以操作所在函数的具名返回值
    关键字 return 并不是一个原子操作,实际上 return 只代表汇编指令ret,即跳转程序执行,比如语句 return i,实际上分为2步执行,即先将i 的值存入栈中作为返回值,然后执行跳转,而defer 语句的执行时机正是在跳转前。

    func foo() (result int) {
        i := 1
        defer func() {
            result++
        }
        
        return i
    }
    

    所以这里return 执行的代码等同于:

    result = i
    result++
    return 
    
数据结构

src/runtime/runtime2.go:_defer定义了 defer 数据结构

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

从其数据结构来看,每个_defer实例实际上是对一个函数的封装,它拥有执行函数的必要信息,比如栈地址,程序计数器,函数地址等。编译器会把每个延迟函数编译成一个_defer实例暂存到数据结构中,待函数结束时再逐个取出执行。

每个 defer 语句对应一个 _defer 实例,多个实例使用指针链接起来形成一个单链表(头部插入),保存到 数据结构中。

type g struct {
    ...
    _defer
    ...
}
image.png
defer 的创建和执行

src/runtime/panic.go 定义了一下两个方法,分别用于创建 defer 和 执行 defer

  • deferproc 负责把 defer 函数处理成 _defer实例,并存入 gorountine 中的链表。
  • deferreturn 负责把 从 defer 从 gorountine 链表中的实例取出并执行。
演进和优化历史

TODO

相关文章

  • go 的 defer 实现原理

    defer 需要注意的2点 defer 函数的参数在defer 语句出现时就已经确定func foo() { ...

  • GO 中 defer的实现原理

    GO 中 defer的实现原理 我们来回顾一下上次的分享,分享了关于 通道的一些知识点 分享了 GO 中通道是什么...

  • Golang之Defer

    引用 golang defer实现原理 Golang之轻松化解defer的温柔陷阱 Golang中defer、re...

  • 我们用GO玩一下验证码

    我们用GO玩一下验证码 嗨,我是小魔童哪吒,咱们上次分享的GO 中 defer 的实现原理,再来回顾一下吧 分享了...

  • Go语言 defer

    参考文章:深入理解Go语言 defer用于资源的释放,会在函数返回之前进行调用 defer关键字的实现跟go关键字...

  • Go函数-延迟调用(三)

    在go语言里,defer可是实现延迟函数调用。语句defer向当前函数注册稍后执行的函数调用。这些调用被称做延迟调...

  • golang defer 特性

    defer.go

  • Go Defer

    Go Defer 如果函数里面有多条defer指令,他们的执行顺序是反序,即后定义的defer先执行。 defer...

  • Go语言——垃圾回收GC

    Go语言——垃圾回收GC 参考: Go 垃圾回收原理 Golang源码探索(三) GC的实现原理 Getting ...

  • goLang异常处理

    defer defer是go提供的一种资源处理的方式。defer的用法遵循3个原则在defer表达式被运算的同时,...

网友评论

      本文标题:go 的 defer 实现原理

      本文链接:https://www.haomeiwen.com/subject/pktlnrtx.html