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

Consider the following function:

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

However:

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

I can't fully understand logic of this behavior: why it would return old value of a after a = a*2

Like @TimCooper commented, you are shadowing "a".

If you run the code below, you will see two different memory addresses.

It means that are "2 variables a".

The "a" inside sum() represents it's own return, and it's declared without a value, so the compiler assigns the "zero value" to the "other a", that is 0 to numeric types.

So, a = a * 2 is equals 0 = 0 * 2.

When the sum() ends, it returns the "other a" (remember the different memory address?), keeping the "first a" unchanged.

This link might be helpful: Go zero values

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
}