【问题标题】:Implicit interface conversion in golanggolang中的隐式接口转换
【发布时间】:2015-10-20 01:37:02
【问题描述】:

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

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方法也只是返回类型不同,是可以转换的。

我提出这个问题的原因是当 interface A, B​​strong> 和 struct C, CA 在不同的包中时,我只能:

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

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

【问题讨论】:

    标签: go interface type-conversion


    【解决方案1】:

    你当前的*C类型没有实现接口B,因此你不能将*C的值赋给B类型的变量,你也不能从持有*C 类型值的东西“类型断言”B 的值。

    这是你可以做的。由于您已经在使用结构字面量 (&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 移动到第三个包,然后定义C 的包将只需要依赖于这个第三个包,但不会依赖于定义B 的包(但仍将隐式实现接口类型B)。

    【讨论】:

      猜你喜欢
      • 2023-03-10
      • 1970-01-01
      • 1970-01-01
      • 2016-06-21
      • 2015-05-16
      • 2012-12-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-21
      相关资源
      最近更新 更多