在一个包中,我有一个接口Repository
,它有一个返回接口GetReporter
的方法Reporter
。这由Execute
函数使用,该函数使用Repository
并通过Reporter
函数获取其GetReporter
。
在另一个包中,我有一个结构GithubRepository
,其方法GetReporter
返回GithubReporter
。
在第三个包中,我想使用Execute
实例从包#1中调用GithubRepository
函数。
我试图使包1和包2彼此独立,没有一个从另一个导入的东西。第三个包应该结合前两个。
Golang回归:
cannot use githubRepository (type GithubRepository) as type Repository in argument to Execute:
GithubRepository does not implement Repository (wrong type for GetReporter method)
have GetReporter(string) GithubReporter
want GetReporter(string) Reporter
代码:
package main
// Package #1
type Repository interface {
GetReporter(string) Reporter
}
type Reporter interface {
ChangeStatus(string) error
}
func Execute(r Repository) {
// Do something with the repository
}
// Package #2
type GithubRepository struct {
}
type GithubReporter struct {
}
func (repo *GithubRepository) GetReporter(sha string) GithubReporter {
return GithubReporter{}
}
func (reporter *GithubReporter) ChangeStatus(status string) error {
// Change the status
return nil
}
// Package #3
func main() {
githubRepository := GithubRepository{}
Execute(githubRepository)
}
答案 0 :(得分:2)
在这种情况下,不可能使两个包独立。但是,使用go1.9及其类型别名,可以这样做。
首先,正如谚语所说,A little copy is better than a little dependency。您应该将Reporter
的定义部分复制到包B,并根据它更改签名:func (repo GithubRepository) GetReporter(sha string) Reporter
。
然而,编译器不理解这两个接口是一样的。但是在type alias的帮助下,它可以解决。将定义type Reporter interface {...}
更改为type Reporter = interface {...}
。它现在将编译。
答案 1 :(得分:0)
使用GithubRepository
和GithubReporter
作为值接收器,因为您没有将变量创建为指针。并在方法GetReporter
func (repo GithubRepository) GetReporter(sha string) Reporter {
return GithubReporter{}
}
func (reporter GithubReporter) ChangeStatus(status string) error {
// Change the status
return nil
}
希望这会有所帮助。
请参阅操作:https://play.golang.org/p/Gugm3LetqHU
如果你在不同的包中有接口,这些就不需要做特殊的事情了,只需指向那个包的接口。
在包A中
package A
type Repository interface {
GetReporter(string) Reporter
}
type Reporter interface {
ChangeStatus(string) error
}
func Execute(r Repository) {
r.GetReporter("report:r").ChangeStatus("status:s")
}
在包B中
package B
import (
"fmt"
"test/A"
)
type GithubRepository struct {
}
type GithubReporter struct {
}
func (repo GithubRepository) GetReporter(sha string) A.Reporter {
fmt.Println(sha)
return GithubReporter{}
}
func (reporter GithubReporter) ChangeStatus(status string) error {
// Change the status
fmt.Printf(status)
return nil
}
您可以尝试Import Dot