如何确定延迟语句的参数
defer 语句表达式的值在定义时就已经确定了。下面通过三个不同的函数来理解:
func t1() {
var err error
defer fmt.Println(err)
err = errors.New("defer1 error")
return
}
func t2() {
var err error
defer func() {
fmt.Println(err)
}()
err = errors.New("defer2 error")
return
}
func t3() {
var err error
defer func(err error) {
fmt.Println(err)
}(err)
err = errors.New("defer3 error")
return
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
运行结果:
<nil>
defer2 error
<nil>
1
2
3
2
3
第 1 和第 3 个函数中,因为作为参数,err 在函数定义的时候就会求值,并且定义的时候 err 的值都是 nil,所以最后打印的结果都是 nil;第 2 个函数的参数其实也会在定义的时候求值,但第 2 个例子中是一个闭包,它引用的变量 err 在执行的时候值最终变成 defer2 error 了。
现实中第 3 个函数比较容易犯错误,在生产环境中,很容易写出这样的错误代码,导致最后 defer 语句没有起到作用,造成一些线上事故,要特别注意。
上次更新: 5/9/2023, 10:58:32 AM