Skip to content

Instantly share code, notes, and snippets.

@MutatedBread
Last active May 20, 2019 13:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MutatedBread/cd51aeb243db7efc96541e676b2411ae to your computer and use it in GitHub Desktop.
Save MutatedBread/cd51aeb243db7efc96541e676b2411ae to your computer and use it in GitHub Desktop.
A note on using pointer or value receiver in a golang function.
func (s *MyStruct) pointerMethod() { } // method on pointer
func (s MyStruct)  valueMethod()   { } // method on value
  1. Receiver behaves like an argument given to a function.
  2. Perserve consistency for a struct, if use pointer, use pointer for all, vise versa.

Use Pointer

  1. Function needs to modify the receiver
  2. Use this for efficiency when struct is big.

Use value

  1. The receiver is just a copy of the original. Variables changed will not be reflected at the object.
  2. Duplication, maybe add more garbage to collector. Cheap to make if struct, slices and basic types are small. Unless semantics requires that.

Extracted from https://golang.org/doc/faq#methods_on_values_or_pointers

Copied note

  • If the receiver is a map, func or chan, don't use a pointer to it.
  • If the receiver is a slice and the method doesn't reslice or reallocate the slice, don't use a pointer to it.
  • If the method needs to mutate the receiver, the receiver must be a pointer.
  • If the receiver is a struct that contains a sync.Mutex or similar synchronizing field, the receiver must be a pointer to avoid copying.
  • If the receiver is a large struct or array, a pointer receiver is more efficient. How large is large? Assume it's equivalent to passing all its elements as arguments to the method. If that feels too large, it's also too large for the receiver.
  • Can function or methods, either concurrently or when called from this method, be mutating the receiver? A value type creates a copy of the receiver when the method is invoked, so outside updates will not be applied to this receiver. If changes must be visible in the original receiver, the receiver must be a pointer.
  • If the receiver is a struct, array or slice and any of its elements is a pointer to something that might be mutating, prefer a pointer receiver, as it will make the intention more clear to the reader.
  • If the receiver is a small array or struct that is naturally a value type (for instance, something like the time.Time type), with no mutable fields and no pointers, or is just a simple basic type such as int or string, a value receiver makes sense.
  • A value receiver can reduce the amount of garbage that can be generated; if a value is passed to a value method, an on-stack copy can be used instead of allocating on the heap. (The compiler tries to be smart about avoiding this allocation, but it can't always succeed.) Don't choose a value receiver type for this reason without profiling first.
  • Finally, when in doubt, use a pointer receiver.

Copied from https://github.com/golang/go/wiki/CodeReviewComments#receiver-type

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment