我试图概括我的一些代码,我认为我可能可以将一些通用代码放在一起,但是我遇到了类型系统问题。
假设我有一个这样的界面:
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
需要的字段,但这似乎是一个更糟糕的选择。
有一个干净的解决方案吗?
答案 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))