我正在练习编写惯用的 Go 代码,发现接口应该在使用它们的包中声明,因为它们是隐式的。但是我遇到了这种情况,在第二个包(包 b)中,我想要一个函数来调用包 a 中的结构的接收函数,而不紧密耦合它。
所以很自然地,我在包 b 中声明了一个接口,其中包含我想从包 a 调用的函数的签名。问题是这个函数接受一个特定类型的参数,这个参数是在包 a 中声明的接口。因为我不希望包 b 导入包 a,所以我在包 b 中定义了一个接口,其签名与包 a 中存在的签名完全相同。下面的 playground 链接显示了示例代码。
package main
import (
"fmt"
"log"
)
func main() {
manager := &Manager{}
coach := NewRunnerCoach(manager)
fmt.Println("Done")
}
// package a
type Runner interface {
Run()
}
type Manager struct {
}
func (o *Manager) RegisterRunner(runner Runner) {
log.Print("RegisterRunner")
}
func (o *Manager) Start() {
log.Print("Start")
}
// package b
type RunnerCoach struct {
runner *FastRunner
}
func NewRunnerCoach(registerer runnerRegisterer) *RunnerCoach {
runnerCoach := &RunnerCoach{&FastRunner{}}
registerer.RegisterRunner(runnerCoach.runner)
return runnerCoach
}
type FastRunner struct {
}
func (r *FastRunner) Run() {
log.Print("FastRunner Run")
}
// define ther registerer interface coach is accepting
type runnerRegisterer interface {
RegisterRunner(runner RunnerB)
}
// declaring a new interface with the same signature because we dont want to import package a
// and import Runner interface
type RunnerB interface {
Run()
}
此代码无法编译。所以这里的问题是,我是在错误地使用接口,还是应该在单独的包中定义具体类型,或者最后,是否有更好的代码模式来解决我要解决的问题?
编辑:澄清一下,包 a 和 b 不会相互导入。main() 代码存在于连接这两者的单独包中。
慕容3067478
呼唤远方
相关分类