Consider the following example. I don’t fully understand what happens “in the background” and seek an explanation. This version seems to make a copy of the struct Foo when I call AddToEntry from the main function. Right? How can I “proof” this in the code?
When go makes a copy of the struct, I am just manipulating the copy of the struct and when I get back to the main function I see the original as before?
When I expect a pointer (see comment in the code), everything is fine, my struct is not copied. How can avoid this kind of “error”? How can I make sure I am not copying the struct? Is there a possible compile time/run time check for that, or do I have be careful?
package main
import (
"fmt"
)
type Foo struct {
Entry []string
}
func MakeFoo() Foo {
a:=Foo{}
a.Entry = append(a.Entry,"first")
return a
}
// if I change (f Foo) to (f *Foo), I get
// the "desired" result
func (f Foo) AddToEntry() {
f.Entry = append(f.Entry,"second")
}
func main() {
f:=MakeFoo()
fmt.Println(f) // {[first]}
f.AddToEntry()
fmt.Println(f) // {[first]}
}
Your method signature is
func (f Foo) AddToEntry(). The way methods work,f.AddToEntry()is is the same as:The receiver is just another parameter. Why is this important? What happens when you pass a struct and modify it in a function? In C, Go, and other pass by value languages, the struct given in the parameter is only a copy. Therefore, you can not modify the original. Only return the new struct.
When you define
func (f *Foo) AddToEntry(), you are defining the receiver, the first parameter, as a pointer. Obviously, given a pointer, you can modify the original struct. What is hidden is that you are implicitly referencing when you access a struct in Go. To put it another way,(*ptrFoo).Entryis the same asptrFoo.Entryin Go.So the issue here is that for those unaccustomed to go, the syntax is hiding some of what is going on. In C, you would never be able to edit a struct unless you passed a pointer to it. The same happens in Go. You need to use a pointer receiver in order to modify what you are receiving.