Defer 延迟处理函数
特点
1. defer的运行的时间实在函数体运行的最后,在return之前
1. 多个 defer 的执行顺序为“后进先出/先进后出”
return 和defer 的关系
return的本质其实应该包含前后两个步骤:第一步是给返回值赋值(若为有名返回值则直接赋值,若为匿名返回值则先声明再赋值,第二步是调用 return 返回指令并传入返回值,而 return 则会检查 defer 是否存在,若存在就先逆序插播 defer 语句,最后 return 携带返回值退出函数
因此,return 和defer 的运行顺序应该是: return最先给返回值赋值;接着 defer 开始执行一些收尾工作,最后 return 指令携带返回值退出函数
举个栗子:
// return的数据和返回值同样是tmp,因此defer里的数据操作会影响返回值数值
func Demo01() (tmp int) {
tmp = 0
fmt.Println("函数体内,defer前", tmp)
defer func() {
tmp++
fmt.Println("函数体内,defer里", tmp)
}()
fmt.Println("函数体内,defer后", tmp)
return tmp
}
/*
结果如下
函数体内,defer前 0
函数体内,defer后 0
函数体内,defer里 1
1(return 的tmp数据)
*/
// return的数据和返回值不同,因此defer里的数据操作不会影响返回值数值
func Demo02() int {
tmp := 0
fmt.Println("函数体内,defer前", tmp)
defer func() {
tmp++
fmt.Println("函数体内,defer里", tmp)
}()
fmt.Println("函数体内,defer后", tmp)
return tmp
}
/*
结果如下
函数体内,defer前 0
函数体内,defer后 0
函数体内,defer里 1
0(return 的tmp数据)
*/
// 函数中有多个defer的时候运行顺序类似栈,是先入后出
func Demo03() int {
tmp := 0
fmt.Println("函数体内,defer前", tmp)
defer func() {
tmp++
fmt.Println("函数体内,defer里1", tmp)
}()
defer func() {
tmp++
fmt.Println("函数体内,defer里2", tmp)
}()
fmt.Println("函数体内,defer后", tmp)
return tmp
}
/*
结果如下
函数体内,defer前 0
函数体内,defer后 0
函数体内,defer里2 1
函数体内,defer里1 2
0(return 的tmp数据)
*/