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
}