defer语句执行机制

1.规则

  • 延迟函数的参数在defer语句出现时已经确定
func a(){
  i := 0
  defer fmt.Println(i)  // 函数输出0
  i++
  return
}

函数参数值在defer出现时就已经确定了下来 即拷贝了一份 后续对i的修改不会影响原始延迟函数中的执行 输出0

  • 延迟函数执行按后进先出顺序执行 即先出现的defer最后执行
    根据goroutine可以对此进行理解

  • 延迟函数可能操作主函数的具名返回值

    • 首先 Go语言中允许在表明返回类型时可以顺便给返回值定义名字
func a(b int) // 定义返回名b

此时b为具名返回值
- 其次 我们需要直到return在汇编执行中并不是原子操作 它需要分为两步运行

func a(b int){
 i := 1
 return i
}
# 分步
b = i
return (此时return的值是b 也即是说在返回前需要将i的值赋给真正的返回值b

延迟函数的执行正好在return之前

b = i
defer语句
return

看一个例子

func a(b int){
  i := 1
  defer func(){
      b++
   }()
  return i
}

此时执行顺序是

b = i
b++
return b

对于返回字面值来说 defer语句无法操作其返回值
对于返回匿名变量来说 defer操作该返回值的前提是延迟函数参数中传入的是匿名变量的地址 才有可能操作返回值

func foo() int {
   var i int

   defer func() {
     i++
   }()

   return i
 }
此时操作的返回值并不是i 假定return有一个变量来存储真正的返回值 则步骤如下
a = i  // a是真正的返回值
i++
return a

这样的defer延迟函数对函数返回值不受影响

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容