defer对返回值的影响

题目:

下面代码输出什么?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
func increaseA() int {
var i int
defer func() {
i++
}()
return i
}

func increaseB() (r int) {
defer func() {
r++
}()
return r
}

func main() {
fmt.Println(increaseA())
fmt.Println(increaseB())
}
  • A. 1 1
  • B. 0 1
  • C. 1 0
  • D. 0 0

答案解析:

B。

​ 在Go语言的函数中的return语句在底层并不是原子操作,它分为 返回值赋值RET指令两部分,而 defer的执行时机就在返回值赋值操作后,RET指令执行前。

​ 对于 increaseA()来说,先进行返回值赋值,即 返回i的值赋值给一个临时变量,值为0(待执行RET指令后,再将该变量返回到调用该函数的地方);再调用defer语句,将 i++,此时并不会影响到返回值,故输出为0

​ 对于increaseB()来说,不同的是,它的返回值参数是具名返回值,这样系统就不会为它创建一个新变量,而是直接将返回值赋值该具名返回值上,然后调用defer语句后的函数,将返回值 r++,故此时的返回值变为1.


defer对返回值的影响
http://example.com/2023/07/09/Go每日一题/defer对返回值的影响/
作者
Feng Tao
发布于
2023年7月9日
更新于
2023年7月9日
许可协议