The official Go site FAQ states, “As in all languages in the C family, everything in Go is passed by value”. This is because the function gets a copy of everything that is passed in.
Is there such thing as pass by reference in Go?
There are different views as to what is exactly pass by reference to Go. Some strongly maintain there is no such thing as pass by reference. In C++ terms, the actual meaning of pass by reference is you pass a reference or a pointer to the actual data structure rather the data itself. The function then can modify the value of the argument using that reference.
In Go when I pass a pointer to a struct for example, whether its a copy to the pointer or not, I am not passing the struct itself but a pointer or a reference to it. I can modify the actual struct using the pointer. In my view, that fits the definition of pass by reference.
When to pass a pointer?
We don’t need to pass pointers to map and slices as they are already descriptors that contain pointers to the actual map or slice data.
Compelling arguments to use pointer receiver and pass by reference:
- You want to modify the receiver. With value receivers you can’t modify the struct itself
- Its is a big struct. It will cost to deep copy the struct.
When you pass a slice to a function, since it is a pointer to an array you just get a copy of the slice structure. It will still point to the same underlying array segment. So any modifications made to the slice within the function will be seen outside.
However, if you append an element, remember that a new slice is created and elements are copied over so you will lose the elements if this happens within a function so you must return a slice. E.g. append from the stdlib returns a new slice.
Whatever it is you choose to use, stay consistent. Coming from a C++ background, I always thought pass by reference is cheaper than passing by value. But apparently it is not always the case in Go.