syntax - 为什么 Go 方法接收类型不能是接口(interface)?

标签 syntax interface methods go

来自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 和任何特定的游戏实现可能位于不同的包中。

Here is some discussion on golang-nuts

关于syntax - 为什么 Go 方法接收类型不能是接口(interface)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6237113/

相关文章:

java - Collection<E> 和 Set<E> 是一样的吗?

java - 如何返回 java 中最后添加的项目的最后一个主键?

java - 点 x 值无故变化

PowerShell 字符串插值语法

syntax - 方案切换语句语法

Java:扩展类并实现具有相同方法的接口(interface)

c# - 验证泛型类型是否实现了某个接口(interface)

类中的c++回调语法

delphi - 我可以在 Delphi 中创建特定接口(interface)的通用列表吗?

java - 在 Java 中的同一类的另一个方法中使用一个方法