Go语言入门9(defer延迟处理函数)

发布时间 2023-04-20 17:07:42作者: te9uila

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数据)
*/