教程集 www.jiaochengji.com
教程集 >  Golang编程  >  golang教程  >  正文 Defer

Defer

发布时间:2023-01-28   编辑:jiaochengji.com
教程集为您提供Defer等资源,欢迎您收藏本站,我们将为您提供最新的Defer资源

引用

  • golang defer实现原理
  • Golang之轻松化解defer的温柔陷阱
  • Golang中defer、return、返回值之间执行顺序的坑

使用

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.


到此这篇关于“Defer”的文章就介绍到这了,更多文章或继续浏览下面的相关文章,希望大家以后多多支持JQ教程网!

您可能感兴趣的文章:
go那些事儿|defer必掌握知识
golang中的defer recover panic
defer ,panic,recover
Golang Defer详解
Golang中defer关键字实现原理
Go: defer与return小记
golangdefer特性姿势还是有必要了解下的!!!
Golang defer解读
go 延迟函数 defer
defer函数参数求值简要分析

[关闭]
~ ~