dqwh2717 2015-07-29 07:43
浏览 103
已采纳

Golang中的隐式接口转换

Here is an example of the idea I want to demonstrate.

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

In this example

  • interface B has a method Get to return an interface A
  • struct C has a member function Get to return a pointer to struct CA, which implements interface A

The result is Go can't deduce interface B from struct C, even their Get method is only different in returning type, which is convertible.

The reason I raise this question is when interface A, B and struct C, CA are in different packages, I can only:

  • refine the Get method of C to func Get() A, which introduce some dependency between packages.
  • refine both Get method of interface B and struct C to func Get() interface{}

I want to avoid dependency between packages and try not to rely on interface{}, can anyone give me some hint? What's the best practice in Go?

  • 写回答

1条回答 默认 最新

  • dourong9253 2015-07-29 08:08
    关注

    Your current *C type does not implement the interface B, therefore you can't assign a value of *C to a variable of type B nor can't you "type assert" a value of B from something holding a value of type *C.

    Here's what you can do. Since you're already using a struct literal (&C{}), you may declare c to be of type *C of which you can call its Get() method, and you can convert the return value of C.Get() to A (because the return value does implement 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())
    

    Output:

    it's CA
    it's CA
    

    Or refactor:

    The problem is that you have an interface (B) which you want to implement, which has a method which returns another interface (A). To implement this B interface, you have to have dependency to the package that defines A, you can't avoid this. And you have to declare C.Get() to return A (instead of a concrete struct type).

    You may move A to a 3rd package and then the package that defines C will only have to depend on this 3rd package, but will not depend on the package that defines B (but still will implicitly implement the interface type B).

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 win11 23H2删除推荐的项目,支持注册表等
  • ¥15 matlab 用yalmip搭建模型,cplex求解,线性化处理的方法
  • ¥15 qt6.6.3 基于百度云的语音识别 不会改
  • ¥15 关于#目标检测#的问题:大概就是类似后台自动检测某下架商品的库存,在他监测到该商品上架并且可以购买的瞬间点击立即购买下单
  • ¥15 神经网络怎么把隐含层变量融合到损失函数中?
  • ¥15 lingo18勾选global solver求解使用的算法
  • ¥15 全部备份安卓app数据包括密码,可以复制到另一手机上运行
  • ¥20 测距传感器数据手册i2c
  • ¥15 RPA正常跑,cmd输入cookies跑不出来
  • ¥15 求帮我调试一下freefem代码