基于接口抽象实现一个'Stringer'
Implement a 'Stringer' abstractly based on an interface
我正在尝试实现一个接口 'abstractly'。我的意思是我试图根据另一个接口的方法来实现该接口的方法。
这是我尝试过的方法(但它不起作用,因为似乎我们不允许使用接口类型作为接收者):
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中我们可以很容易地避免这种重复;例如通过向抽象中添加具体方法 class;或者通过向接口中的某些方法添加 'default' 实现。
有没有一种'idiomatic'的方法可以在go中完成这种事情? (也就是说,我们能否使抽象类型如 Symbol
实现 Stringer
而无需复制 String()
的实现。
您不能拥有类似于调用具体实现方法的抽象基 class 的结构。有很多方法可以模拟,但我猜这不是你要问的。
在Go中,接口只是一个方法列表,不存在class继承的概念。您可以使用类型嵌入构建对象层次结构,但这不提供实现此功能所需的后期绑定。
但是,您可以这样做:
为符号创建纵梁函数:
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)}
我正在尝试实现一个接口 'abstractly'。我的意思是我试图根据另一个接口的方法来实现该接口的方法。
这是我尝试过的方法(但它不起作用,因为似乎我们不允许使用接口类型作为接收者):
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中我们可以很容易地避免这种重复;例如通过向抽象中添加具体方法 class;或者通过向接口中的某些方法添加 'default' 实现。
有没有一种'idiomatic'的方法可以在go中完成这种事情? (也就是说,我们能否使抽象类型如 Symbol
实现 Stringer
而无需复制 String()
的实现。
您不能拥有类似于调用具体实现方法的抽象基 class 的结构。有很多方法可以模拟,但我猜这不是你要问的。
在Go中,接口只是一个方法列表,不存在class继承的概念。您可以使用类型嵌入构建对象层次结构,但这不提供实现此功能所需的后期绑定。
但是,您可以这样做:
为符号创建纵梁函数:
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)}