Thomas
Thomas

Reputation: 182000

How to create a channel of receive-only channels?

I want to create a channel from which someone can only pull receive-only channels, for instance:

c := make(chan <-chan int)

However, I can't read from this channel:

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

(Playground link) From the error message, it's clear that my syntax chan <-chan is interpreted as chan<- chan, i.e. a send-only channel of channels. Running gofmt even changes the code to reflect this.

So how do I denote the channel type I want?

Upvotes: 0

Views: 1229

Answers (2)

icza
icza

Reputation: 418317

If something is unclear regarding Go's syntax, the language specification should be the first thing to check. Compared to other languages, Go's spec is more readable and shorter.

Exactly this is mentioned in 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)

The answer is there clear and simple in these few quoted lines.

  • The reason for what you experience: the <- operator associates with the leftmost chan possible.
  • The meaning of what you've tried: chan<- chan int is the same as chan<- (chan int)
  • The solution to what you want to achieve (the last line): chan (<-chan int)

Upvotes: 3

Thomas
Thomas

Reputation: 182000

The answer is simple: add parentheses.

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

An alternative, which might be more readable in some situations, would be to create a new type for the inner channel:

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

Upvotes: 3

Related Questions