Go中的接口层次结构



我有一个程序,其中使用了多种类型的模块,但所有不同类型的模块共享某些方法。我试图建立一个通用的工厂,可以为不同类型的模块重用,但我错过了接口继承之类的东西,但是会在Go中调用。

这是一个我试图尽可能简化的例子:

有一个通用工厂使用通用的Module接口:

package main
var (
  modules []Module
)
type Module interface {
  RegisterFlagSet()
  GetName() (string)
}
type Factory struct {
  instances []Module
}
func RegisterModules(modules []Module) {
  modules = modules
}
func (f *Factory) registerFlagSets() {
  for _,inst := range f.instances {
    inst.RegisterFlagSet()
  }
}
func (f *Factory) GetInstance(seek string)(Module) {
  for _,inst := range f.instances {
    if (inst.GetName() == seek) {
      return inst
    }
  }
  panic("cannot find module")
}

然后有一个更具体的模块类型Timer的实现。我正在尝试尽可能多地重用工厂:

package main
import (
  "time"
)
var (
  timer_modules = []Timer{
    // list all the timer modules here
  }
)
type Timer interface {
  Module
  GetTicker() (*time.Ticker)
}
type TimerFactory struct {
  Factory
}
func NewTimerFactory() TimerFactory {
  tfact := TimerFactory{}
  RegisterModules(timer_modules)
  return tfact
}

当我尝试构建时,我得到这个错误:

timer_factory.go:25: cannot use timer_modules (type []Timer) as type []Module in argument to RegisterModules

我不明白为什么type []Timer的一个变量不能用作type []Module,因为接口Module的所有方法都在接口Timer中,所以它们应该兼容还是不兼容?有办法使它们兼容吗?

https://golang.org/doc/faq#convert_slice_of_interface给出了解释。解决方法之一是实现一个新的寄存器函数:

func RegisterModule(m Module) {
  modules = append(modules, m)
}

和调用一个范围内的函数,只需要多花两行代码:

func NewTimerFactory() TimerFactory {
  tfact := TimerFactory{}
  for _, t := range timer_modules {
    RegisterModule(t)
  }
  return tfact
}

修改定时器的声明

type Timer interface {
  Module
  GetTicker()(*time.Ticker)
}

最新更新