Tuesday 23 May 2017

Golang gotcha #2: Methods without pointer receivers cannot modify the actual receiver object

One gotcha that most newcomers to the language run into involves pointer receivers. A method on a struct is declared with a receiver such as those above. Meow is a method on struct type Cat with a receiver of c. c here is similar to self in Python, though we name it by convention as an acronym of the struct name rather than self. In the first example, when Meow() is called, c, the instance the method is called on, is passed as though it were an argument of the method.

If the method were instead defined with a pointer receiver as in the second example, then c would evaluate to a reference to the Cat instance.

Thus the impact of using non-pointer receivers is:
1) Additional memory overhead from copying.
2) Immutability of the actual receiver. This is the major gotcha, this means that methods declared with a non-pointer receiver cannot persist changes to the instance outside the scope of the method.

See this example for a demonstration:
https://play.golang.org/p/aRSViFKlGn

I think that non-pointer receiver methods are more trouble than they are worth. It may seem wise to use them on methods that do not mutate the instance such as Get() and the like but there is a real danger it will come back to bite you in the form of a hard to diagnose bug.

Notable mention in golang docs:
https://golang.org/doc/faq#methods_on_values_or_pointers

No comments:

Post a Comment