golang使用defer要注意了

思考下面的代码输出什么?

package main

import "fmt"

func main() {
    fmt.Println(test())
    fmt.Println(test1())
}

func test() (result int) {
    defer func() {
        result++
    }()
    return 1
}

func test1() (result int) {
    t := 5
    defer func() {
        t = t + 5
    }()
    return t
}

结果为:

2
5

return XXX 不是一条原子指令,函数返回过程是,先对返回值赋值,再调用defer函数,然后返回调用函数
所以test方法的return 1可以拆分为:

result = 1
func()(result int){
    result ++
}()
return

共 5 个回复


Gkond

你好.我这边有些问题,有时间麻烦解答下哈。defer应该是函数返回之前执行的?这边作为return 1,可以看成是result := 1,然后是函数返回return,所以执行了defer,那test1呢。为什么不是10呢。

# 0

stevewang

defer是在return之后,函数真正返回之前执行的。
test里的defer函数修改了返回值result所以直接影响了返回值;test1里的defer函数只修改了t而非返回值result所以返回值不受影响。

# 1

2bwithu

就一个知识点defer执行时机,这种考试题风格的代码,工程上基本碰不到

# 3

lpf

@2bwithu 有时候这种小知识点也会引起大问题的,这种小知识点还是很有必要搞清楚的

# 4