golang中的隐式接口转换

Implicit interface conversion in golang

这是我想展示的想法的一个例子。

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")
}

在这个例子中

结果是 Go 无法从结构 C 中推导出接口 B,即使他们的 Get 方法只是在 returning 类型上不同,它是可转换的.

之所以提这个问题是因为interface A,Bstruct C,CA在不同的包里,我只能:

我想避免包之间的依赖,尽量不依赖接口{},谁能给我一些提示吗? Go 的最佳实践是什么?

您当前的 *C 类型 没有 实现接口 B,因此您不能将 *C 的值分配给B 类型的变量也不能从持有 *C.

类型值的对象中 "type assert" 值 B

您可以执行以下操作。由于您已经在使用结构文字 (&C{}),因此您可以将 c 声明为 *C 类型,您可以调用它的 Get() 方法,并且您可以将 C.Get() 的 return 值转换为 A(因为 return 值确实实现了 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),它有一个方法 return 是另一个接口 (A)。要实现这个 B 接口,你必须依赖定义 A 的包,你无法避免这一点。并且您必须将 C.Get() 声明为 return A(而不是具体的结构类型)。

您可以将 A 移动到第三个包,然后定义 C 的包将只依赖于这个第三个包,而不依赖于定义 [=13] 的包=](但仍将隐式实现接口类型B)。