我正在尝试为订阅编写一个通用的包装器,例如:
type Subscriber interface{
Subscribe(addr string) chan interface{}
}
假设有一个我想要使用的库,其中有一个订阅方法,但它使用chan library.Object
。我希望能够做到这样的事情:
func (s *mySubscriber) Subscribe(addr string) chan interface{}{
ch := make(chan library.Object)
library.Subscribe(addr, ch)
return chan interface{}(ch)
}
目前,我不相信这样的演员阵容是可能的。而且我不想修改底层库,因为包装器应该与库实现无关。
我已经看过Is there a way to cast Structs for sending over a channel,但在这种情况下,可以修改应用程序以满足需要。在这里,它不能。这可能吗?还有更好的方法吗?
一种解决方案是将一般用途频道传入“订阅”,并在chan library.Object
上无限制地等待并解除在我的一般频道上发生的任何事情,但我并不特别喜欢引入另一个频道通道只是为了绕过类型演员。
答案 0 :(得分:5)
不,你不能仅仅通过演员来做到这一点。正如您已经考虑过的那样,您必须使用额外的频道。幸运的是,已经有了一个帮助库(免责声明:我写了它)。你想要Wrap
函数。
答案 1 :(得分:1)
对于遇到此问题并想要一些内联代码的其他人:
// wrap a timeout channel in a generic interface channel
func makeDefaultTimeoutChan() <-chan interface{} {
channel := make(chan interface{})
go func() {
<-time.After(30 * time.Second)
channel <- struct{}{}
}()
return channel
}
// usage
func main() {
resultChannel := doOtherThingReturningAsync()
cancel := makeDefaultTimeoutChan()
select {
case <-cancel:
fmt.Println("cancelled!")
case results := <-resultChannel:
fmt.Printf("got result: %#v\n", results)
}
}