在实现Go接口时,如何处理重复性和灵活性?

在实现Go接口时,如何处理重复性和灵活性?,go,Go,我有一个项目使用这样的结构: type I interface { GetName() string DoSomething() } // // A implements I // type A struct { Name string } func (a *A) GetName() string { return a.Name } func (a *A) DoSomething() { ...do something } // // B implements

我有一个项目使用这样的结构:

type I interface {
  GetName() string
  DoSomething()
}

//
// A implements I
//
type A struct {
    Name  string
}

func (a *A) GetName() string {
  return a.Name
}

func (a *A) DoSomething() {
  ...do something
}

//
// B implements I
//
type B struct {
    Name  string
}

func (b *B) GetName() string {
  return b.Name
}

func (b *B) DoSomething() {
  ...do something
}

func (b *B) DoSomethingElse() {
  ...do something else
}

//
// Both
//
func UseAorB(T I) {
  name := T.GetName()...
}
  • 在使用接口I的函数中调用时,使用GetName是否是从结构A或结构B获取名称字段的最佳方法
  • 我是否每次都必须为实现接口的每件事情重新定义DoSomething?或者,如果剂量每次都是相同的,我可以定义一次,那么有没有更好的方法来做到这一点
  • 结构B有一个接口未定义的方法(DoSomethingElse)。我是否需要使用reflect将结构B传递给使用接口I调用DoSomethingElse的函数?或者我应该定义一个包含此方法的新接口吗
  • 我想提高我的代码质量并编写一个可靠的库,但我不得不说,我觉得我在与语言作斗争,使我的生活更加困难

  • 是的,
    GetName()
    是一种很好的方法

  • 如果有类似的方法实现,通常可以将其移动到公共结构并嵌入:

    type Common struct {}
    
    func (c Common) DoSomething() {...}
    
    type A struct {
       Common
       Stuff
    }
    
    type B struct {
       Common
       Other stuff
    }
    
    上面,
    A
    B
    都有
    DoSomething
    方法,它们共享实现

  • 不要使用反射。有两种方法:

  • 使用类型断言:

    func f(in I) {
       if b, ok:=in.(B); ok {
          // b is of type B, so:
          b.DoSomethingElse()
       }
    }
    
    type DoesSometingElse interface {
       DoSomethingElse()
    }
    
    func f(in I) {
       if x, ok:=in.(DoesSomethingElse); ok{
          x.DoSomethingElse()
       }
    }
    
  • 使用接口和类型断言:

    func f(in I) {
       if b, ok:=in.(B); ok {
          // b is of type B, so:
          b.DoSomethingElse()
       }
    }
    
    type DoesSometingElse interface {
       DoSomethingElse()
    }
    
    func f(in I) {
       if x, ok:=in.(DoesSomethingElse); ok{
          x.DoSomethingElse()
       }
    }
    

  • 如果您觉得自己在与该语言作斗争,那么您要么是建模错误,要么是不知道用该语言做某事的正确方法。所有语言都有好的和坏的做事方式,而且很多时候,每种语言的方式都不同。如果你是从另一种语言开始学习围棋,你应该先停止用另一种语言思考,然后翻译围棋,试着单独使用围棋。

    如果接口的每个实现都完全相同,这可能意味着你不需要接口。除非你解释一下
    DoSomething
    实际做什么,很难建议您应该使用什么结构。相关/可能重复:;非常棒。嵌入结构是在实现同一接口的多个结构实例之间共享公共功能的最佳方式。