• defer


    为什么需要defer?

      在函数中,程序员经常需要创建资源(比如:数据库连接、文件句柄、锁等),为了在函数执行完毕后,及时的释放资源,Go的设计者提供defer (延时机制)。

    快速入门案例:

    func sum(n1 int, n2 int) int {

      //当执行到defer时,暂时不执行,会将defer后面的语句压入到独立的栈中(defer栈)
      //当函数执行完毕后,再从defer栈中按照先入后出的方式出栈。
      defer fmt.Println("ok1 n1=", n1) //defer 3. ok1 n1=10
      defer fmt.Println("ok2 n2=", n2) //defer 2. ok2 n2=20
      res := n1 + n2 //res = 30
      fmt.Println("ok3 res=", res) //1. ok3 res=30
      return res
    }

    func main() {
      res := sum(10,20)
      fmt.Println("res = ", res) //4. res = 30
    }


    输出后的结果:

    defer 的注意事项和细节:

    细节说明:

      1)当go执行到一个defer时,不会立即执行defer后的语句,而是将defer 后的语句压入到一个栈中,然后继续执行函数下一个语句。

      2)当函数执行完毕后,在从defer 栈中,依次从栈顶取出语句执行(注:遵守栈 先入后出的机制),所以看到上面案例输出的顺序。

      3)在defer 将语句放入到栈时,也会将相关的值拷贝同时入栈。

    案例:

    func sum(n1 int, n2 int) int {

      //当执行到defer时,暂时不执行,会将defer后面的语句压入到独立的栈中(defer栈)
      //当函数执行完毕后,再从defer栈中按照先入后出的方式出栈。
      defer fmt.Println("ok1 n1=", n1)   //defer 3. ok1 n1=10
      defer fmt.Println("ok2 n2=", n2)   //defer 2. ok2 n2=20
      //增加一句话
      n1++   
      n2++   
      res := n1 + n2   
      fmt.Println("ok3 res=", res)   //1. ok3 res=32
      return res
    }

    func main() {
      res := sum(10,20)
      fmt.Println("res = ", res) //4. res = 32
    }

    输出的结果是:

    defer 的最佳实践:

      defer 最主要的价值是在,当函数执行完毕后,可以及时的释放函数创建的资源。

    说明:

      1)在golang编程中的通常做法是,创建资源后,比如(打开了文件句柄,获取了数据库的连接,或者是锁资源),可以执行 defer file.Colse()  和 defer connect.Close()。

      2)在 defer 后,可以继续使用创建资源。

      3)当函数完毕后,系统会依次从 defer 栈中,取出语句,关闭资源。

      4)这种机制非常简洁,程序员不用再为在什么时机关闭资源而烦心了。

  • 相关阅读:
    MySQL日期比较
    MySQL日期函数、时间函数总结(MySQL 5.X)
    MySQL日期、字符串、时间戳互转
    通过 zxing 生成二维码
    前台时间格式 2019-03-09T16:00:00.000Z
    基于vue-cli配置手淘的lib-flexible + rem,实现移动端自适应
    python爬虫实例大全
    python3 BeautifulSoup模块使用
    Python 通过sgmllib模块解析HTML
    如何搭建一个合理的数值框架?
  • 原文地址:https://www.cnblogs.com/green-frog-2019/p/11355127.html
Copyright © 2020-2023  润新知