Golang defer 传值问题

看这段 golang 片段:

package main

import "fmt"

func main() {
    x := 1
    defer func(a int) {
        fmt.Println("a =", a)
    }(x)

    defer func() {
        fmt.Println("x =", x)
    }()

    x++
}

运行结果:
x = 2
a = 1

这里 a = 1 不太理解,传值的时候这里 x 为什么不是自增后的 2 呢?

阅读 8.9k
4 个回答

因为你第一个

defer func(a int) {
        fmt.Println("a =", a)
}(x)

是传参数的 x,运行到这里的时候,x = 1。所以打印结果 a = 1

我的理解是:

defer func(a int) {
        fmt.Println("a =", a)
}(x)

这里的x是一个形数,如楼上,运行到这里的时候x是1,而下面

defer func() {
        fmt.Println("x =", x)
}()

这里是一个闭包,x引用函数外面的x,所以这里的x是2

defer 其实是延迟执行。所以执行到 defer 的时候,其实已经加载了状态了,也就是已经传参 x 了。因为这样传参是值复制,所以,在执行的时候,a 的值就是 1 了。

下面呢是个闭包函数,也就是在函数内的 x 和外面的 x 是同一个变量,地址也是一样的。所以当你改变了 x 的值,里面的 x 也必定是更改了。

defer 调用的函数参数的值在 defer 定义时就确定了, 而 defer 函数内部所使用的变量的值需要在这个函数运行时才确定.我这么解释你就明白了吧。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题