鸭子输入:如何在Go中从一个接口隐式转换为另一个接口

时间:2018-11-21 23:07:52

标签: go interface type-conversion

我是新手,我希望在用途和提供者之间使用(非常)松散耦合的API制作两个软件包。为此,我希望使用go的功能隐式实现接口和隐式转换。

提供者和用户都有自己定义的接口(例如,提供者返回提供者A,而用户接受用户A)。 通过这种模式,我可以从一种类型转换为另一种类型,而不用从另一个包中导入接口。

这在简单的接口上可以很好地工作,但是一旦方法将接口作为输入,从一种类型到另一种类型的转换就变得不可能了。

为什么不允许这种转换?有什么解决方法吗?

工作示例:

package main

// Provider

type A interface{
    AddString(string)
}


type a struct{
    b string
}
func (a *a) AddString(b string) {
    a.b = b
}
func NewA() A {
    return &a{nil}
}


// User

type A2 interface{
    AddString(string)
}

func Main() {
    var _ A2 = NewA()
}

导致问题的示例:

package main

// Provider

type A interface{
    AddB(B)
}
type B interface{}


type a struct{
    b B
}
func (a *a) AddB(b B) {
    a.b = b
}
func NewA() A {
    return &a{nil}
}


// User

type A2 interface{
    AddB(B2)
}
type B2 interface{}

func Main() {
    var _ A2 = NewA() // error..
}

1 个答案:

答案 0 :(得分:2)

Go提供类型检查作为功能,而不是错误。当您将B和B2声明为单独的类型时,编译器会尊重这一区别,并以不同的方式对待它们。

一个熟悉的示例是 var arr : [String?] = [nil, "b", nil, "a", nil] arr = arr.sorted{ $0 ?? "" < $1 ?? "" } if let ix = arr.firstIndex(where: {$0 != nil}) { arr = arr.suffix(from: ix) + Array(repeating: nil, count: ix) } // [Optional("a"), Optional("b"), nil, nil, nil] ,它仅是一个time.Duration来计数纳秒,但是如果没有显式类型,则不能混合和匹配int64int64的变量转换。 see time.Duration docs

与其尝试解决Go的类型检查功能,不如尝试学习如何使用惯用的Go表达算法。