使用场景
在函数中,经常需要创建资源(比如数据库连接,文件句柄,锁等),为了在函数执行完毕后,及时的释放资源,Go的设计者提供defer(延时机制)来实现
类似javascript里面的微任务、宏任务
执行效果
- 当执行到 defer 时,暂时跳过不执行,将defer后面的语句压入一个新的栈中(姑且称为defer栈)
- 当函数其它代码执行完毕后,再从defer栈,按照 先入后出 的方式出栈,执行
- 将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
// 测试值拷贝
n1++
n2++
fmt.Println("n1=", n1) // n1= 11
fmt.Println("n2=", n2) // n2= 21
res := n1 + n2
fmt.Println("res=", res) // 1 res= 32
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、连接数据库时,操作完成之后,断开连接,关闭数据库