golang

时间:2015-07-29 07:43:37

标签: go interface type-conversion

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

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,用于返回指向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的最佳实践?

1 个答案:

答案 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)。