I am contemplating on the Go pointers, passing variables as parameters to functions by value or by reference. In a book I have encountered a good example, which is the first code snippet below, on passing a pointer.
The first version is working as expected, in function that takes parameter of a pointer makes changes to the variable itself, not on a copy of it. But the second example below I am tinkering with works on a copy of it. I have thought they should behave equivalently, and second one to work on the variable passed as parameter, not on copy of it.
Essentially, what these two versions of the function is behaving different?
version in the book, passing parameters by reference:
package main
import (
"fmt"
)
// simple function to add 1 to a
func add1(a *int) int {
*a = *a+1 // we changed value of a
return *a // return new value of a
}
func main() {
x := 3
fmt.Println("x = ", x) // should print "x = 3"
x1 := add1(&x) // call add1(&x) pass memory address of x
fmt.Println("x+1 = ", x1) // should print "x+1 = 4"
fmt.Println("x = ", x) // should print "x = 4"
}
my alternative tinkering version, passing pointer parameter:
package main
import (
"fmt"
)
// simple function to add 1 to a
func add1(a int) int {
p := &a
*p = *p+1 // we changed value of a
return *p // return new value of a
}
func main(){
fmt.Println("this is my go playground.")
x := 3
fmt.Println("x = ", x) // should print "x = 3"
x1 := add1(x) // call add1(&x) pass memory address of x
fmt.Println("x+1 = ", x1) // should print "x+1 = 4"
fmt.Println("x = ", x) // should print "x = 4"
}
Why should they behave equivalently? In the first example you pass a pointer (to int
), in the second example you pass an int
value.
What happens in the 2nd example is that you pass an int
value. Parameters in functions work like local variables. A local variable called a
of type int
will be created, and will be initialized with the value you passed (3
which is the value of x
). This local variable is addressable like any other variables.
You take its address (p := &a
) and you increment the value pointed by this pointer (which is variable a
itself). And you return the value pointed by it which is the incremented value of a
.
Outside from where you called this add1()
function, the value of x
is not modified because only the local copy a
was modified.
Everything in golang
is pass by value
, which means the function always gets a copy of the thing being passed. In your second example, the value of x
is actually sent to the function add
, so any modification you made to the copy wont affect the original x
.
See pass by value