一、defer
1. 作用
-
用defer关键字修饰的语句会被延迟到函数即将返回前执行
-
defer常被用于在函数调用结束后,进行一些收尾工作,如关闭文件描述符、关闭数据库连接以及解锁资源等
-
当存在多个defer语句时,执行顺序类似于数据结构中栈的形式,先进后出
代码示例:
package main
import "fmt"
func deferDemo(){
fmt.Println("start")
defer fmt.Println("defer1")//defer将该条语句延迟到函数即将返回前执行
defer fmt.Println("defer2")//多个defer执行,类似于数据结构中栈的形式,先进后出
defer fmt.Println("defer3")
fmt.Println("end")
}
func main(){
deferDemo()
}
2. defer在return中执行顺序
在Go中,return语句不是原子操作,而是被拆成了两步:
package main
import "fmt"
func f1(x int,y int) int{
return x+y
}
func main(){
f1()
}
- 返回值等于x+y;
- ret指令
而defer语句就是在这两步之间执行:
- 返回值等于XXX
- defer
- ret指令
更进一步解释,请看下面例子:
package main
func f() int {
i := 5
defer func() {
i++
}()
return i
}
func f1() (result int) {
defer func() {
result++
}()
return 0
}
func f2() (r int) {
t := 5
defer func() {
t = t + 5
}()
return t
}
func main() {
println(f())
println(f1())
println(f2())
}
输出结果:
5
1
5
解释:
对于f(),返回值等于5(此时i为5),执行defer,i++(i变为6),返回5;
对于f1(),返回值为result,执行defer,result++,result变为1,返回result(1);
对于f2(),返回值为r(此时r等于t,为5),执行defer,t变为10,返回r(5)。