函数的延迟调用

* 本页面主要介绍Go语言函数的延迟调用的相关内容。

这个defer绝对是在其他编程语言中很难遇到的东西,是Go语言里独有的关键字,但你可能也会在其他编程语言中找到类似的影子,比如C++的析构函数,但是他们大不相同(defer实现在函数里面)。go 语言的defer功能强大,对于资源管理非常方便,但是如果没用好,也会有陷阱。

defer的使用场景

一般来讲,我们把defer用于以下场景中:

  • 关闭文件句柄
  • 锁资源释放
  • 数据库连接释放
  • 处理异常,特别是一些很难捕捉到到异常(来源于操作系统内核或者硬件提示的异常信息)
defer的特性
  • 关键字 defer 用于注册延迟调用
  • 这些调用直到包含该defer语句的函数执行完毕时(无论是正常的return返回,还是由于panic异常导致结束)才被执行
  • 多个defer语句,按先进后出的方式执行,即与声明的顺序相反
  • defer语句中的变量,在defer声明时就决定了,即当defer被声明时,其参数就会被实时解析
  • defer可以读取有名返回值
  •   func deferFunc1() (i int ) { 
        defer func() { i++ }()// step2: 会继续操作i++ 
        return i // step1: 返回值会复制给一个临时变量,再返回出去 
      }
defer碰上闭包
  package main

  import "fmt"

  func main() {
      var whatever [5]struct{}
      for i := range whatever {
          defer func() { fmt.Println(i) }()
      }
  }

  //输出结果
  4
  4
  4
  4
  4

函数正常执行,由于闭包用到的变量 i 在执行的时候已经变成4,所以输出全都是4。

另外要注意,滥用 defer 可能会导致性能问题,尤其是在一个 "大循环" 里。所以这里也需要切记不能滥用。 更多可以参考函数function的第八部分。

这部分内容就总结到这里,了解了不?


* 本页内容参考以下数据源:

  • 《Go程序设计语言》
  • https://blog.csdn.net/zhghost/article/details/100738098
  • https://www.cnblogs.com/wongbingming/p/12840677.html

凯冰科技 · 代码改变世界,技术改变生活
Next Page→