Defining golang struct function using pointer or not
As mentioned in the FAQ
Should I define methods on values or pointers?
func (s *MyStruct) pointerMethod() { } // method on pointer
func (s MyStruct) valueMethod() { } // method on value
First, and most important, does the method need to modify the receiver? If it does, the receiver must be a pointer. (Slices and maps act as references, so their story is a little more subtle, but for instance to change the length of a slice in a method the receiver must still be a pointer.)
In the examples above, if pointerMethod modifies the fields of s, the caller will see those changes, but valueMethod is called with a copy of the caller's argument (that's the definition of passing a value), so changes it makes will be invisible to the caller.
In your case, func (s Sample) Append(name string)
modifies a copy.
laher reminds us in the comments that using a value instead of pointer also means getting a copy, and respecting the immutable nature of an object::
You'd want to use the non-pointer
valueMethod
when (for nstance) you're returning a [value derived from an] 'immutable' private property.
See "Why are receivers pass by value in Go?":
Can be useful if for instance you have a small immutable object. The caller can know for certain that this method doesn't modify it's receiver.
They can't know this if the receiver is a pointer without reading the code first.
Go slices are a tricky beast. Internally, a variable of slice type (like []int
) looks like this:
struct {
data *int // pointer to the data area
len int
cap int
}
When you pass a slice to a function, this structure is passed by value, while the underlying data area (i.e. what data
points to) is not copied. The builtin append()
function modifies the data
area (or generates a new one) and returns a new slice with updated len
, data
, and cap
values. If you want to overwrite anything that is not part of the underlying data area, you need to pass a pointer to the slice or return a modified slice.