这是我想要展示的想法的一个例子 .
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")
}
在这个例子中
-
interface
B
有一个方法Get
返回一个接口A
-
struct
C
有一个成员函数Get
,用于返回指向structCA
的指针,该指针实现了接口A
结果是Go无法从struct C
中推断出界面 B
,即使它们的 Get
方法仅在返回类型中是不同的,这是可转换的 .
我提出这个问题的原因是当 interface A, B 和 struct C, CA 在不同的包中时,我只能:
-
将
C
的Get方法细化为 func Get() A ,这会在包之间引入一些依赖关系 . -
将
Get
接口Get
和structC
的方法细化为 func Get() interface{}
我想避免包之间的依赖,尽量不要依赖 interface{} ,任何人都可以给我一些提示吗? Go的最佳做法是什么?
1 回答
您当前的
*C
类型 does not 实现了接口B
,因此您不能将*C
的值分配给B
类型的变量,也不能将B
的值分配给B
的值B
.这里's what you can do. Since you'已经使用了结构文字(
&C{}
),您可以将c
声明为*C
类型,您可以将其调用为Get()
方法,并且可以将C.Get()
的返回值转换为A
(因为返回值确实实现A
) :输出:
Or refactor:
问题是你有一个你想要实现的接口(
B
),它有一个返回另一个接口的方法(A
) . 要实现此B
接口,您必须依赖于定义A
的包,您无法避免这种情况 . 并且您必须声明C.Get()
以返回A
(而不是具体的结构类型) .您可以将
A
移动到第3个包,然后定义C
的包只需依赖于此第3个包,但不依赖于定义B
的包(但仍将隐式实现接口类型B
) .