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

Channels with interface type and pointers to structs as concrete types

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

假设我有这样的界面:

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 需要的字段,但这似乎是一个更糟糕的选择。

是否有一个干净的解决方案?

问题是: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