go中的闭包:命名返回值的不同输出

go中的闭包:命名返回值的不同输出,go,Go,考虑以下功能: func main() { var a int = 3 sum := func() {a = a*2} sum() sum() fmt.Println(a) // returns 12 } 然而: func main() { var a int = 3 sum := func() (a int) {a = a*2; return} sum() sum() fmt.Println(a) // returns 3 } 我不能完全理解这种行为

考虑以下功能:

func main() {
  var a int = 3
  sum := func() {a = a*2}
  sum()
  sum()
  fmt.Println(a) // returns 12
}
然而:

func main() {
  var a int = 3
  sum := func() (a int) {a = a*2; return}
  sum()
  sum()
  fmt.Println(a) // returns 3
}

我不能完全理解这种行为的逻辑:为什么它会在a=a*2之后返回a的旧值,就像@TimCooper评论的那样,你在跟踪a

如果运行下面的代码,您将看到两个不同的内存地址

这意味着有两个变量a

内部和表示它自己的返回,声明时没有值,因此编译器将零值分配给另一个a,即0分配给数值类型

所以,a=a*2等于0=0*2

当总和结束时,它返回另一个a“记住不同的内存地址吗?”,保持第一个a不变

此链接可能会有所帮助:

我不能完全理解这种行为的逻辑:你在跟踪变量a;有什么让人困惑?@TimCooper:Go的返回值可能会被命名。如果是这样,它们将被视为在函数顶部定义的变量。这澄清了这个问题。这不是意识形态的封闭行为。
package main

import "fmt"

func main() {
    var a int = 3
    sum := func() (a int) {
        fmt.Println(&a) // func sum() scope (a's copy memory address)
        a = a * 2
        return
    }
    b := sum()      // initializing b with the sum() return
    fmt.Println(&a) // func main() scope (a's memory address)
    fmt.Println(b)  // func sum() return
    fmt.Println(a)  // old value, stills 3
}