go

go 的defer 执行顺序

package main import "fmt" // 核心规则4 // return 语句不是原子操作,它分为两步: //第一步:将返回值(若有命名返回值则直接赋值,若无则创建临时变量)赋值为 return 后面的表达式。 //第二步:执行所有已注册的 defer 函数(后注册先执行)。 //第三步:函数真正返回。 //命名返回值(如 (r int))在…

3 阅读

package main

import "fmt"

// 核心规则4
// return 语句不是原子操作,它分为两步:

//第一步:将返回值(若有命名返回值则直接赋值,若无则创建临时变量)赋值为 return 后面的表达式。

//第二步:执行所有已注册的 defer 函数(后注册先执行)。

//第三步:函数真正返回。

//命名返回值(如 (r int))在函数开始时就已声明并初始化为零值,return 语句会先给这个变量赋值。

// defer 函数的参数在 defer 语句被执行到时就已经求值(值拷贝),而 defer 函数体内部对变量的修改是否影响外部,取决于它捕获的是变量本身(闭包)还是副本(参数)。

func f1() (r int) {
	defer func() {
		r++
	}()
	return 0 //r=0 再执行 defer  r=1
}

func f2() (r int) {
	t := 5
	defer func() {
		t = t + 5
	}()
	return t // 创建临时变量=5  t+5无效
}

func f3() (r int) {
	defer func(r int) {
		r = r + 5
	}(r)
	return 1 // r=1  defer 使用拷贝了一份,使用内部变量
}

func f4() (r int) {
	defer func() {
		r = r + 5
	}()
	return 1 // r=1  defer后=6
}

func main() {
	fmt.Println(f1()) //1
	fmt.Println(f2()) //5
	fmt.Println(f3()) //1
	fmt.Println(f4()) //6

}
正在加载评论…