这是我要展示的想法的一个例子。
package main
import "fmt"
// interface declaration
//
type A interface {
AAA() string
}
type B interface{
Get() A
}
// implementation
//
type CA struct {}
// implementation of A.AAA
func (ca *CA) AAA() string {
return "it's CA"
}
type C struct {}
// implementation of B.Get, except for returning a 'struct' instead of an 'interface'
func (c *C) Get() *CA {
return &CA{}
}
func main() {
var c interface{} = &C{}
d := c.(B)
fmt.Println(d.Get().AAA())
fmt.Println("Hello, playground")
}
在这个例子中
B
有一个方法Get
来返回接口A
C
有一个成员函数Get
,用于返回指向struct CA
的指针,该指针实现接口A
结果是Go无法从结构B
中推断出界面C
,即使他们的Get
方法在返回类型方面也是不同的,这是可转换的。
我提出这个问题的原因是接口A,B 和 struct C,CA 在不同的包中时,我只能:
C
的Get方法细化为 func Get()A ,这会在包之间引入一些依赖关系。Get
和结构B
的{{1}}方法细化为 func Get()interface {} 我想避免软件包之间的依赖关系,尽量不要依赖 interface {} ,任何人都可以给我一些提示吗?什么是Go的最佳实践?
答案 0 :(得分:3)
您当前的*C
类型不实现接口B
,因此您无法将*C
的值分配给{{1}类型的变量1}}也不能从类型为B
的值中“键入”B
的值。
这是你能做的。由于您已经在使用结构文字(*C
),因此您可以将&C{}
声明为c
类型,您可以将其称为*C
方法,然后您就可以将Get()
的返回值转换为C.Get()
(因为返回值确实实现了A
):
A
输出:
var c *C = &C{}
var a A = c.Get() // This is ok, implicit interface value creation (of type A)
fmt.Println(a.AAA())
// Or without the intermediate "a", you can simply call:
fmt.Println(c.Get().AAA())
或重构:
问题是你有一个你想要实现的接口(it's CA
it's CA
),它有一个返回另一个接口(B
)的方法。要实现此A
接口,您必须依赖于定义B
的包,您无法避免这种情况。而且你必须声明A
返回C.Get()
(而不是具体的结构类型)。
您可以将A
移动到第3个包,然后定义A
的包只需要依赖第3个包,但不依赖于定义C
的包(但仍会隐式实现接口类型B
)。