Go syntax has some funny peculiarities which are not immediately obvious, like methods on primitive types. Let's have a look.
Primitive wrapper types
Anyone with a few hours of Go is familiar with the basic object notation, like this example:
Try it on http://play.golang.org/p/GUgWEz_nXd
Looking for simplicity
The problem, of course, is that not only is this useless, it is also ugly, because we are wrapping a primitive type in a useless struct
. What we probably would like would be something like this, like one can do in Ruby, where all types are objects which can receive methods:
But if we try this, the Go compiler complains, as you can see on http://play.golang.org/p/95YSh_rmBo
A solution
Now, Go has the ability to assign types to other types:
Unlike in some languages where types are first-class objects, this is not aliasing: the two types will be different when compared, but offer the same capabilities. And this brings us the expected capability:
Run it on http://play.golang.org/p/Y49wr_gYPo
There we have it : we added a method on a type which is a copy of a primitive type. No struct boxing, no unboxing in the method.
Why it matters
The real beauty of this is actually not the ability to attach the method, although this is definitely satisfying from a conceptual point of view, bringing consistency with an approach opposite to that or Ruby, it is rather the code in the Add()
method itself, and the last line in main()
are actually the beauty of the thing : since our local Int
type is actually just a name for the intrinsic int
, it still support the builtin operators like naked ints: no explicit casts needed to use the aliased variable in an expression.
Is it possible to define an operator override ?
Is it possible to define a struct method to override "+" itself? To have Int(5) + Int(6) for example?
Operators cannot be overridden
I think I already saw this asked on #golang-nuts more than once : Go1.x does not allow this, and it seems unlikely to appear in 2.x if the current language direction remains stable : see https://golang.org/doc/faq#overloading explicitly rejecting this.