0%

go_defer

go defer

go defer 命名和匿名返回值函数中的返回结果不同

函数示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package main

import "fmt"

func f1() int {
var res int
defer func() {
res++
}()
return res
}

func f2() (res int){
defer func() {
res++
}()
return res
}

func f3() (res int) {
defer func() {
res++
}()
return 1
}

func f4() (res int) {
defer func() {
res++
}()
res = 1
return res
}

func main() {
x := f1()
y := f2()
z := f3()
zz := f4()
fmt.Println("x: ", x, "y: ", y, "z: ", z, zz)
}

输出:

1
x:  0 y:  1 z:  2

解释说明

这里以匿名返回函数f1()作说明,执行过程如下:
首先函数返回时会自动创建一个返回变量假设为ret,函数返回时要将res赋值给ret,即有ret = res,也就是说ret=0
然后检查函数中是否有defer存在,若有则执行defer中部分,此时就到了res++
最后返回ret
从上面过程可以看到,函数返回的是ret,即0,虽然defer中res++但是是给res做加减,res和ret是两个变量;

但是在命名返回值f2()中就会有不一样的结果,因为返回值在函数定义时以经存在,return时不需要再创建另外的变量ret,返回的ret就是res,只有一个变量,所以res++就是给实际返回的ret做加减,最终返回结果当然是1了。

f3() 等同于 f4()

defer在命名和匿名返回函数中表现不一样,这是一个很大的坑,使用中要多多注意。