具有接口类型和结构指针的通道作为具体类型

时间:2018-12-02 17:50:42

标签: go interface channel

我试图概括我的一些代码,我认为我可能可以将一些通用代码放在一起,但是我遇到了类型系统问题。

假设我有一个这样的界面:

type Hashable interface {
    GetHash() []byte
}

我有几个具体的类型,例如:

type Transaction struct {
    Hash                 []byte    `protobuf:"bytes,1,opt,name=hash,proto3" json:"hash,omitempty"`
}

func (m *Transaction) GetHash() []byte {
    if m != nil {
        return m.Hash
    }
    return nil
}

请注意,它们是由protoc生成的,我可能不容易对其进行更改。尽管类型本身未实现Hashable,但如果我没有记错的话,指向该结构的指针也应该如此。

当我创建一个接受类型为chan Hashable的通道并尝试传递chan *Transaction的函数时,就会出现问题:

func consume(c chan Hashable) {
    // Do something with the elements from c
}

func main() {
    var c2 chan *Transaction
    consume(c2)
}

(我创建了一个小示例,在Playground中显示了此问题)

我当然可以创建一个新结构来重新包装consume需要的字段,但这似乎是一个更糟糕的选择。

有一个干净的解决方案吗?

1 个答案:

答案 0 :(得分:1)

问题是:chan *Transaction不是接口-它是特定类型。因此,它本质上无法实现接口或chan Hashable。您需要使用特定的频道。

您可以像这样通过灌浆将Transaction的值即时转换为Hashable

func convertor(ct chan *Transaction) chan Hashable {
    ch := make(chan Hashable)
    go func() {
        for t := range(ct) {
            ch <- Hashable(t)
        }

    }()
    return ch
}

并致电

consume(convertor(c2))

https://play.golang.org/p/pd2EfhCehYz