【问题标题】:Explicitly choosing implementation methods for interfaces in Go在 Go 中显式选择接口的实现方法
【发布时间】:2020-09-15 21:02:09
【问题描述】:

假设我必须遵循实现Foo 的接口FooAB

type Foo interface {
    SayHi()
    SayBye()
}

type A struct {}

func(a A) SayHi() {}

func(a A) SayBye() {}

type B struct {}

func(b B) SayHi() {}

func(b B) SayBye() {}

如果我想要来自ASayHi 方法,但是来自BSayBye 方法,那么最好的语法方法是什么?

我总是可以做到的:

type AB struct {
    a A
    b B
}

func(ab AB) SayHi() { ab.a.SayHi() }

func(ab AB) SayBye() { ab.a.SayBye() }

但这需要我为每个方法创建一个包装器。另一种方法是将AB 嵌入到AB 中,但这会产生冲突。

【问题讨论】:

  • 您可以通过结构嵌入来做到这一点,如下所示:play.golang.org/p/74RphthhN36 但老实说,我无法想象有必要这样做的场景
  • 您的解决方案@Kosanovic 没有实现可能需要的接口Foo。但它更易于阅读。如果您将其作为答案发布,我会投票赞成。

标签: go methods struct interface embedding


【解决方案1】:

您可以嵌入 2 个 interface 类型,它们仅定义您想要使用(“继承”)不同类型的部分(方法):

type AB struct {
    Hier
    Byer
}

type Hier interface {
    SayHi()
}
type Byer interface {
    SayBye()
}

基本上使用HierByer“掩码”其他方法,因此嵌入它们(而不是AB)将解决名称冲突(歧义)。

让我们让实现打印他们是谁以进行验证:

func (a A) SayHi()  { fmt.Println("A says Hi") }
func (a A) SayBye() { fmt.Println("A says Bye") }
func (b B) SayHi()  { fmt.Println("B says Hi") }
func (b B) SayBye() { fmt.Println("B says Bye") }

使用它:

var ab Foo = AB{
    Hier: A{},
    Byer: B{},
}
ab.SayHi()
ab.SayBye()

输出将是(在Go Playground 上尝试):

A says Hi
B says Bye

当然,如果我们现在有HierByer,我们可以使用它们来简化Foo,如果我们想这样做:

type Foo interface {
    Hier
    Byer
}

【讨论】:

  • 这需要手动定义2个单独的接口,其中包含已经定义的方法(SayHiSayBye已经是Foo的一部分),但是因为我没有看到更好的方法为此,我会投票并接受。
  • @thestateofmay 是的,这需要“一些”额外的工作,但是您不必像在您的问题中那样添加方法实现,只需添加方法声明即可。如果您考虑一下:您必须以某种方式从AB 中说出您想要哪些方法,并且指定方法就是声明它的工作。另请注意,如果您在声明Foo 时重用HierByer(如答案末尾的建议),那么您实际上只需声明每个方法一次。
猜你喜欢
  • 2021-08-08
  • 2010-11-03
  • 2011-05-28
  • 2018-04-16
  • 2011-05-01
  • 2016-06-27
  • 1970-01-01
  • 2016-12-14
  • 2012-12-04
相关资源
最近更新 更多