In this particular case, using pointers will not make a difference. Here's one way to look at it:
In Go, all variables are passed by value. That means:
type T struct {...}
func f(value T) {..}
f(t)
Above, t
is passed as value. That means when f
is called, the compiler creates a copy of t
and passed that to f
. Any modifications f
makes to that copy will not affect the t
used to call f
.
If you use pointers:
func f(value *T) {...}
f(&t)
Above, the compiler will create a pointer pointing to t
, and pass a copy of that to f
. If f
makes changes to value
, those changes will be made on the instance of t
used to call f
. In other words:
type T struct {
x int
}
func f(value T) {
value.x=1
}
func main() {
t:=T{}
f(t)
fmt.Println(t.x)
}
This will print 0, because the modifications made by f
is done on a copy of t
.
func f(value *T) {
value.x=1
}
func main() {
t:=T{}
f(&t)
fmt.Println(t.x)
}
Above, it will print 1, because the call to f
changes t
.
Same idea applies to methods and receivers:
type T struct {
x int
}
func (t T) f() {
t.x=1
}
func main() {
t:=T{}
t.f()
fmt.Println(t.x)
}
Above program will print 0, because the method modifies a copy of t
.
func (t *T) f() {
t.x=1
}
func main() {
t:=T{}
t.f()
fmt.Println(t.x)
}
Above program will print 1, because the receiver of the method is declared with a pointer, and calling t.f()
is equivalent to f(&t)
.
So, use pointers when passing arguments or when declaring methods if you want to modify the object, or if copying the object would be too expensive.
This is only a small part of the story about pointer arguments.