美文网首页
Golang之Defer

Golang之Defer

作者: 8411e9740257 | 来源:发表于2020-02-28 18:16 被阅读0次

引用

使用

defer是golang提供的关键字,在函数或者方法执行完成,返回之前调用。
每次defer都会将defer函数压入栈中,调用函数或者方法结束时,从栈中取出执行,所以多个defer的执行顺序是先入后出。

Defer规则

  • 延迟函数的参数在defer语句出现时就已经确定下来了
  • 延迟函数执行按后进先出顺序执行,即先出现的defer最后执行
  • 延迟函数可能操作主函数的具名返回值

触发时机

1.包裹着defer语句的函数返回时
2.包裹着defer语句的函数执行到最后时
3.当前goroutine发生Panic时

返回值执行顺序

  1. 先给返回值赋值
  2. 执行defer语句
  3. 包裹函数return返回
    因此,defer、return、返回值三者的执行顺序应该是:return最先给返回值赋值;接着defer开始执行一些收尾工作;最后RET指令携带返回值退出函数。

defer命令的拆解

理解这些坑的关键是这条语句:

return xxx

上面这条语句经过编译之后,变成了三条指令:

1. 返回值 = xxx
2. 调用defer函数
3. 空的return

1,3步才是Return 语句真正的命令,第2步是defer定义的语句,这里可能会操作返回值。
下面我们来看两个例子,试着将return语句和defer语句拆解到正确的顺序。

第一个例子:

func f() (r int) {
     t := 5
     defer func() {
       t = t + 5
     }()
     return t
}

拆解后:

func f() (r int) {
     t := 5
     
     // 1. 赋值指令
     r = t
     
     // 2. defer被插入到赋值与返回之间执行,这个例子中返回值r没被修改过
     func() {        
         t = t + 5
     }
     
     // 3. 空的return指令
     return
}

这里第二步没有操作返回值r, 因此,main函数中调用f()得到5.

第二个例子:

func f() (r int) {
    defer func(r int) {
          r = r + 5
    }(r)
    return 1
}

拆解后:

func f() (r int) {
     // 1. 赋值
     r = 1
     
     // 2. 这里改的r是之前传值传进去的r,不会改变要返回的那个r值
     func(r int) { 
          r = r + 5
     }(r)
     
     // 3. 空的return
     return
}

因此,main函数中调用f()得到1.

相关文章

  • Golang之Defer

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

  • 2017-12-04

    Golang,Panic,Defer,Recover 在golang中,recover在defer里发挥作用。 一...

  • go defer理解

    golang的defer是怎么工作的?defer在golang里是一个很基础的关键字,在函数内部使用defer声明...

  • golang 之 defer

    defer的详细讲解

  • golang中defer执行时机与常见问题

    defer是什么? defer的用途 defer的执行时机 了解defer的执行时机首先要知道golang的ret...

  • 聊聊golang的defer

    序 本文主要研究一下golang的defer defer return先赋值(对于命名返回值),然后执行defer...

  • 12 Golang defer panic recover

    defer Golang中的defer会将其后面跟随的语句进行延迟处理。在defer归属的函数即将返回时,将延迟处...

  • 2017-11-23 step

    1 Golang的返回值,return,defer 多个defer的顺序是stack顺序,FILO 正确的顺序是:...

  • Golang defer

    话题起于同事在微信群里发了张图,是Go Newsletter于13日在Twitter上转的一个代码截图,问输出是啥...

  • golang defer

    The arguments to the deferred function (which include the...

网友评论

      本文标题:Golang之Defer

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