使用场景

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

类似javascript里面的微任务、宏任务

执行效果

  1. 当执行到 defer 时,暂时跳过不执行,将defer后面的语句压入一个新的栈中(姑且称为defer栈)
  2. 当函数其它代码执行完毕后,再从defer栈,按照 先入后出 的方式出栈,执行
  3. 将defer语句放入栈时,也会将相关的值拷贝,同时入栈(深拷贝)

    看代码

    ```go package main

import “fmt”

func sum(n1 int, n2 int) int { // 当执行到 defer 时,暂时跳过不执行,将defer后面的语句压入一个新的栈中(defer栈) // 当函数其它代码执行完毕后,再从defer栈,按照先入后出的方式出栈,执行 // 可以用来函数执行完毕之后,释放加载的资源 defer fmt.Println(“defer n1=”, n1) // 3 defer n1= 10 // 值拷贝 defer fmt.Println(“defer n2=”, n2) // 2 defer n2= 20

  1. // 测试值拷贝
  2. n1++
  3. n2++
  4. fmt.Println("n1=", n1) // n1= 11
  5. fmt.Println("n2=", n2) // n2= 21
  6. res := n1 + n2
  7. fmt.Println("res=", res) // 1 res= 32
  8. return res

}

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

n1= 11 n2= 21 res= 32 defer n2= 20 defer n1= 10 main-res= 32 // defer拷贝的变量不影响最后的计算结果, 11 + 21 ```

最佳实践

1、读取文件时,读写完成之后,关闭文件
2、连接数据库时,操作完成之后,断开连接,关闭数据库