Tom*_*ver 5 methods syntax interface go
接收器类型必须是T或*T形式,其中T是类型名称.T称为接收器基类型或仅基类型.基类型不能是指针或接口类型,必须在与方法相同的包中声明.
任何人都可以给我一些有关为什么会这样的见解?是否有其他(静态类型)语言允许这样做?我真的想在接口上定义方法,所以我可以将给定接口类型的任何实例视为另一个.例如(如果以下内容有效,则从模板方法模式的维基百科文章中窃取示例):
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接口之上定义一个更多的方法
这可能与 Java 中无法在接口上定义方法的原因相同。
接口是对一组对象的外部接口的一部分或全部的描述,而不是它们如何实现底层行为。在 Java 中,如果您需要预定义部分行为,您可能会使用抽象类,但我认为在 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 和任何特定游戏实现可能位于不同的包中。