基于接口抽象地实现“Stringer”

我正在尝试“抽象地”实现一个接口。我的意思是我试图根据另一个接口的方法来实现该接口的方法。


这是我尝试过的方法(但它不起作用,因为似乎我们不允许使用接口类型作为接收器):


package symbols


import "fmt"


type Symbol interface {

    Name() string

}


type TerminalSymbol struct {

    rune rune

}


func (t TerminalSymbol) Name() string {

    return `'` + string(t.rune) + `'`

}


type NonTerminalSymbol struct {

    name string

}


func (nt NonTerminalSymbol) Name() string {

    return nt.name

}


/////////////////////////////////////////////////////////

/// Try to implement 'Stringer' interface for Symbols


func (s Symbol) String() string {

    //^ ERROR: invalid receiver type Symbol (pointer or interface type)

    return fmt.Sprintf("A symbol with name: %v", s.Name())

}

我想 go 编译器本质上是在告诉我,根本不支持基于另一个接口实现一个接口?


我想我可以简单地接受提示并改为这样做:


func (s NonTerminalSymbol) String() string {

    return fmt.Sprintf("A symbol with name: %v", s.Name())

}


func (s TerminalSymbol) String() string {

    return fmt.Sprintf("A symbol with name: %v", s.Name())

}

这行得通,但最终会重复“String”方法的实现。


在 Java 中,我们可以很容易地避免这种重复;例如,通过向抽象类添加具体方法;或者通过向接口中的某些方法添加“默认”实现。


有没有一种“惯用”的方式来完成这种事情?(也就是说,我们可以在不Symbol复制.StringerString()


慕神8447489
浏览 98回答 1
1回答

白衣非少年

您不能拥有类似于调用具体实现方法的抽象基类的结构。有很多方法可以模拟它,但我猜这不是你要问的。在 Go 中,接口只是一个方法列表,不存在类继承的概念。您可以使用类型嵌入构建对象层次结构,但这不提供实现它所需的后期绑定。但是,您可以这样做:为符号创建纵梁函数:func SymbolToString(s Symbol) string {       return fmt.Sprintf("A symbol with name: %v", s.Name())}String现在您可以为每个结构编写简单的方法实现:type NonTerminalSymbol struct {    name string}func (n NonTerminalSymbol) String() string {return SymbolToString(n)}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go