【发布时间】:2019-08-14 19:33:28
【问题描述】:
我正在尝试通过使用接口来打破合理规模的 golang 项目中的循环依赖关系。我有一些这样的嵌套结构:
// these are in one package...
type config struct {
region string
}
type system struct {
name string
config config
}
func (s system) getName() string {
return s.name
}
func (s system) getConfig() config {
return s.config
}
func (c config) getRegion() string {
return c.region
}
在另一个想要使用它们的包中,我声明了一些相应的嵌套接口:
type iConfig interface {
getRegion() string
}
type iSystem interface {
getName() string
getConfig() iConfig
}
// and has functions like
func New(system iSystem) {
fmt.Printf("region=%s", system.getConfig().getRegion())
}
但是当我尝试像这样使用它们时:
theSystem := system{
name: "testName",
config:config{
region:"testRegion",
},
}
New(theSystem) // doesn't work
我收到一个错误:
cannot use theSystem (type system) as type iSystem in argument to New:
system does not implement iSystem (wrong type for getConfig method)
have getConfig() config
want getConfig() iConfig
似乎因为我的具体system 结构返回一个具体类型config,Go 认为它不满足iConfig 接口——即使我可以通过iConfig 接口直接使用config。我期待config 隐含地满足iConfig 接口,但这并没有发生。我该如何解决这个问题?
这是Go Playground的链接。
【问题讨论】:
-
“我期待
config隐式满足iConfig接口,但事实并非如此。” 这实际上是正在发生的事情,只是因为config实现了iConfig这并不意味着system实现iSystem,方法签名不同,这就是您收到错误的原因。通过have与want的解释,错误消息非常清楚。要修复它,您可以更新system的getConfig方法的签名以返回接口而不是具体类型。 -
我不能这样做,因为我试图让每个包为它需要的对象类型声明自己的私有接口。我有多个包,每个包都声明了它们需要的具体对象的方法的一些变体。如果我再次走上单一接口的路线,我最终会像以前一样使用循环导入。