繁体   English   中英

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

在这个例子中

  • 接口B有一个方法Get返回接口A
  • struct C有一个成员函数Get返回一个指向struct CA的指针,它实现了接口A

结果是Go不能从struct C推导出接口B ,即使它们的Get方法只在返回类型中是不同的,它是可转换的。

我提出这个问题的原因是当接口A,Bstruct C,CA在不同的包中时,我只能:

  • C的Get方法细化为func Get()A ,它引入了包之间的一些依赖关系。
  • 将接口B和结构C Get方法细化为func Get()接口{}

我想避免包之间的依赖,尽量不依赖于接口{} ,任何人都可以给我一些提示吗? Go的最佳做法是什么?

您当前的*C类型实现接口B ,所以你不能的赋值*C到类型的变量B也不能没有你“式的断言”的值, B从一些持有型的价值*C

这是你可以做的。 由于您已经在使用struct literal( &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 (而不是具体的结构类型)。

您可以将A移动到第3个包,然后定义C的包只需依赖于第3个包,但不依赖于定义B的包(但仍会隐式实现接口类型B )。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM