来自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.
谁能告诉我为什么会这样?是否有任何其他(静态类型)语言允许这样做?我真的很想在接口(interface)上定义方法,这样我就可以将给定接口(interface)类型的任何实例视为另一个实例。例如(从 Wikipedia article on the Template Method Pattern 窃取示例)如果以下内容有效:
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()
}
我可以使用任何实现“GameImplementation”的实例作为“游戏”而无需任何转换:
var newGame Game
newGame = NewMonopolyGame() // implements GameImplementation
newGame.PlayOneGame(2)
更新:这样做的目的是尝试实现抽象基类的所有好处,而无需所有与显式层次结构相关的耦合。如果我想定义一个新的行为 PlayBestOfThreeGames,抽象基类将要求我更改基类本身 - 而这里我只是在 GameImplementation 接口(interface)之上再定义一个方法
最佳答案
这可能与您不能在 Java 中的接口(interface)上定义方法的原因相同。
接口(interface)旨在描述一组对象的外部接口(interface)的一部分或全部,而不是它们如何实现底层行为。在 Java 中,如果您需要预定义部分行为,您可能会使用抽象类,但我认为在 Go 中做到这一点的唯一方法是使用函数而不是方法。
我相信对于您的示例,更多 Go 惯用代码将是这样的:
type GameImplementation interface {
InitializeGame()
MakePlay(player int)
EndOfGame() bool
PrintWinner()
}
func PlayOneGame(game GameImplementation, playersCount int) {
game.InitializeGame()
for j := 0; !game.EndOfGame(); j = (j + 1) % playersCount {
game.MakePlay(j)
}
game.PrintWinner()
}
PlayOneGame 和任何特定的游戏实现可能位于不同的包中。
关于syntax - 为什么 Go 方法接收类型不能是接口(interface)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6237113/