如何创建一个只接收通道的通道?

How to create a channel of receive-only channels?

我想创建一个只能从中拉取只接收频道的频道,例如:

c := make(chan <-chan int)

但是,我无法从这个频道阅读:

invalid operation: <-c (receive from send-only type chan<- chan int)

(Playground link) 从错误消息中可以看出,我的语法 chan <-chan 被解释为 chan<- chan,即通道的只发送通道。 运行 gofmt 甚至更改代码以反映这一点。

那么如何表示我想要的频道类型?

答案很简单:加括号。

c := make(chan (<-chan int))

在某些情况下可能更具可读性的替代方法是为内部通道创建一个新类型:

type ReceiveOnlyIntChan <-chan int
c := make(chan ReceiveOnlyIntChan)

如果关于 Go 的语法不清楚,language specification 应该是第一个要检查的东西。与其他语言相比,Go 的规范更具可读性和更短。

正是Spec: Channel types:

中提到的

The <- operator associates with the leftmost chan possible:

chan<- chan int    // same as chan<- (chan int)
chan<- <-chan int  // same as chan<- (<-chan int)
<-chan <-chan int  // same as <-chan (<-chan int)
chan (<-chan int)

在这几行引用中,答案简单明了。

  • 您遇到的原因<- 运算符与最左边的 chan 可能关联。
  • 您所尝试的含义chan<- chan intchan<- (chan int)
  • 相同
  • 你想要实现的解决方案(最后一行):chan (<-chan int)