Golang中defer用法
2020-03-09 本文已影响0人
DevilRoshan
Go语言中的defer
语句会将其后面跟随的语句进行延迟处理。在defer
归属的函数即将返回时,将延迟处理的语句按defer
定义的逆序进行执行,也就是说,先被defer
的语句最后被执行,最后被defer
的语句,最先被执行。
由于defer
语句延迟调用的特性,所以defer
语句能非常方便的处理资源释放问题。比如:资源清理、文件关闭、解锁及记录时间等。
defer执行时机
在Go语言的函数中return
语句在底层并不是原子操作,它分为给返回值赋值和RET指令两步。而defer
语句执行的时机就在返回值赋值操作后,RET指令执行前。具体如下图所示:
![](https://img.haomeiwen.com/i2586653/a27df95afed90749.png)
return最先执行->return负责将结果写入返回值中->接着defer开始执行一些收尾工作->最后函数携带当前返回值退出
defer 不带函数执行,defer可以理解像栈,先进后出
func main() {
defer fmt.Println("one") //第一个进入
defer fmt.Println("two") //第二进入
defer fmt.Println("three") //第三个进入
}
// 按照先进后出的规则输出
three
two
one
defer带函数的执行,defer执行在返回赋值后,返回前执行
func main() {
fmt.Println(test())
}
func test() (res int) {
res = 1
defer func() {
fmt.Println("start", res)
res++
fmt.Println("end", res)
}()
return 7
}
//
start 7
end 8
8
defer注册要延迟执行的函数时该函数所有的参数都需要确定其值
func calc(index string, a, b int) int {
ret := a + b
fmt.Println(index, a, b, ret)
return ret
}
func main() {
x := 1
y := 2
defer calc("AA", x, calc("A", x, y))
x = 10
defer calc("BB", x, calc("B", x, y))
y = 20
}
// defer注册要延迟执行的函数时该函数所有的参数都需要确定其值
A 1 2 3
B 10 2 12
BB 10 12 22
AA 1 3 4
defer经典案例
func f1() int {
x := 5
defer func() {
x++
}()
return x
}
func f2() (x int) {
defer func() {
x++
}()
return 5
}
func f3() (y int) {
x := 5
defer func() {
x++
}()
return x
}
func f4() (x int) {
defer func(x int) {
x++
}(x)
return 5
}
func main() {
fmt.Println(f1())
fmt.Println(f2())
fmt.Println(f3())
fmt.Println(f4())
}
// f1中x返回给return,x再自增跟return没有关系
5
// f2中x为return值,x自增仍被return
6
// f3中如f1
5
// f4defer中x的作用域为后面的参数x,值传递,不影响return的值
5