From the Go documentation on method declarations:
The receiver type must be of the form T or *T where T is a type name. T is called the receiver base type or just base type. The base type must not be a pointer or interface type and must be declared in the same package as the method.
Can anyone give me some insight on why this might be? Are there any other (statically typed) languages that would allow this? I really want to define methods on an interface so I can treat any instance of a given interface type as another. For example (stealing the example from the Wikipedia article on the Template Method Pattern) if the following was valid:
type Game interface {
PlayOneGame(playersCount int)
}
type GameImplementation interface {
InitializeGame()
MakePlay(player int)
EndOfGame() bool
PrintWinner()
}
func (game *GameImplementation) PlayOneGame(playersCount int) {
game.InitializeGame()
for j := 0; !game.EndOfGame(); j = (j + 1) % playersCount {
game.MakePlay(j)
}
game.PrintWinner()
}
I could use any instance implementing “GameImplementation” as a “Game” without any conversion:
var newGame Game
newGame = NewMonopolyGame() // implements GameImplementation
newGame.PlayOneGame(2)
UPDATE: the purpose of this was to try and achieve all the benefits of abstract base classes without all the coupling that goes with an explicit hierarchy. If I wanted to define a new behaviour PlayBestOfThreeGames, abstract base classes would require me to change the base class itself – whereas here I just define one more method on top of the GameImplementation interface
It’s probably for the same reason you can’t define methods on interfaces in Java.
An interface is meant to be a description of a part of, or the whole of, the external interface for a set of objects and not how they implement the underlying behavior. In Java you would probably use an abstract class if you need parts of the behavior to be pre-defined but I think the only way to do that in Go is to use functions rather than methods.
I believe that for your example the more Go idiomatic code would be something like this:
Where PlayOneGame and any specific game implementation are probably living in different packages.
Here is some discussion on golang-nuts