Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/jsf/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Interface 戈朗:我可以向陈界面{}施展吗_Interface_Casting_Go_Publish Subscribe_Channel - Fatal编程技术网

Interface 戈朗:我可以向陈界面{}施展吗

Interface 戈朗:我可以向陈界面{}施展吗,interface,casting,go,publish-subscribe,channel,Interface,Casting,Go,Publish Subscribe,Channel,我正在尝试为订阅编写一个通用包装,类似于: type Subscriber interface{ Subscribe(addr string) chan interface{} } func (s *mySubscriber) Subscribe(addr string) chan interface{}{ ch := make(chan library.Object) library.Subscribe(addr, ch) return chan interf

我正在尝试为订阅编写一个通用包装,类似于:

type Subscriber interface{
    Subscribe(addr string) chan interface{}
}
func (s *mySubscriber) Subscribe(addr string) chan interface{}{
    ch := make(chan library.Object)
    library.Subscribe(addr, ch)
    return chan interface{}(ch)
}
假设我想使用一个库,其中有一个subscribe方法,但它使用了
chan library.Object
。我希望能够做到以下几点:

type Subscriber interface{
    Subscribe(addr string) chan interface{}
}
func (s *mySubscriber) Subscribe(addr string) chan interface{}{
    ch := make(chan library.Object)
    library.Subscribe(addr, ch)
    return chan interface{}(ch)
}
目前,我认为这样的演员阵容是不可能的。我不想修改底层库,因为包装器应该与库实现无关

我看到了,但在这种情况下,可以修改应用程序以满足需要。在这里,它不能。这可能吗?有更好的办法吗


一个解决方案是将一个通用频道传入Subscribe,然后在chan library上无限期地等待。对象并触发我的通用频道上的任何内容,但我并不特别喜欢为了绕过类型转换而引入另一个频道。

不,你不能仅通过类型转换来实现这一点。你必须使用一个额外的频道,正如你已经考虑过的那样。幸运的是,已经有了一个帮助程序库(免责声明:我编写了它)。您需要
Wrap
功能

  • 文件:
  • 代码:

对于其他偶然发现此问题并需要一些内联代码的人:

// 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)
  }
}
//在通用接口通道中包装超时通道

func makeDefaultTimeoutChan()Go没有“强制转换”的概念。进行类型转换、类型断言和接口(以及类型开关),就这样。类型转换最接近于cast-in,例如C。谈论cast和cast-not-working只会模糊您对必须通过使用类型转换来解决的问题的看法(在您的情况下不起作用!),巧妙地使用接口和适当的类型断言/开关可能与反射相结合。围棋中大多数“通用”的东西都注定会失败,或者在沉思中变得缓慢。羞耻。也许在将来,作者会扩展类型切换来支持这一点。对于数组和映射,我们也有同样的问题,但至少在那里,您可以逐个循环元素和类型开关到接口{}。应该有一些方法来处理通道,但可能有一个很好的理由不这样做?不这样做的原因是类型具有根本不同的底层内存布局,因此它不像C中的“cast”那么简单。例如,[]结构{x,y int}看起来与[]接口{}完全不同,所以不能只是“假装”它是一个,您必须进行手动转换。与简单的强制转换不同,转换可能非常昂贵(正如您所说,您必须循环遍历每个元素),因此他们决定不隐藏它,因为它不是同一件事。