具有接口类型和结构指针的通道作为具体类型
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))
我正在尝试概括我的一些代码,我认为我可以将一些通用代码放在一起,但我遇到了类型系统问题。
假设我有这样的界面:
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))