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.

Tags:

Go