一、defer语句
Go语言中的defer
语句会将其后面跟随的语句进行延迟处理。在defer
归属的函数即将返回时,将延迟处理的语句按defer
定义的逆序进行执行,也就是说,先被defer
的语句最后被执行,最后被defer
的语句,最先被执行。
defer执行时机
Go语言的函数中return
语句在底层并不是原子操作,它分为给返回值赋值和RET指令两步。而defer
语句执行的时机就在返回值赋值操作后,RET指令执行前。具体如下图所示:
二、defer 实战
package main
import "fmt"
/**
defer 函数 它在声明时不会立刻去执行,而是在函数 return 后去执行的。
它的主要应用场景有异常处理、记录日志、清理数据、释放资源 等等。
defer 只对当前协程有效。
*/
func main() {
// defer 函数执行顺序
x:=1
y:=2
defer calculate("A",x,y)
x=3
defer calculate("B",x,y)
y=4
defer fmt.Println("1")
defer fmt.Println("2")
defer fmt.Println("3")
defer fmt.Println("main1")
//闭包
var a=1
var b = 2
defer fmt.Println(a+b)
a =5
fmt.Println("main2")
/**
闭包demo1
输出 10 说明闭包获取变量是引用传递,不是值传递
*/
defer func() {
fmt.Println(a+b)
}()
a=8
fmt.Println("main3")
/**
demo2 输出
main4
3
结论:传参到defer 函数中,是值的复制
*/
var c =1
var d =2
defer func(c int,d int) {
fmt.Println(c+d)
}(c,d)
d =9
fmt.Println("main4")
}
func calculate(index string, a, b int) int {
res := a + b
fmt.Println("res=", res)
return res
}
package main
import (
"fmt"
"os"
)
/**
return 不是原子操作
*/
func main() {
// return 函数
fmt.Println("t1=",t1())
fmt.Println("t2=",t2())
fmt.Println("t3=",t3())
fmt.Println("t4=",t4())
// os.Exit 当 os.Exit(0)执行时,defer 函数不会执行
defer fmt.Println("os")
fmt.Println("main")
os.Exit(0)
}
func t1() int{
a:=1
defer func() {
a++
}()
return a
}
func t2()(a int){
defer func() {
a++
}()
return 1
}
func t3()(b int) {
a:=1
defer func() {
a++
}()
return 1
}
func t4()(a int) {
defer func(a int) {
a++
}(a)
return 1
}