Pepijn
Pepijn

Reputation: 4253

How can I transfer a value from one Go channel to another without an implicit buffer?

Imagine I have a goroutine that reads from one channel and writes to another.

ch1 := make(chan int)
ch2 := make(chan int)
go func() {
  for num := range ch1 {
    ch2 <- num+1
  }
}()

If ch2 is blocked, the goroutine will still read a value from ch1, effectively introducing a buffer of 1 in the channel. Since I'm using channels for control flow I don't want any buffering.

How can I make a pipeline that executes in a completely lock-step fashion? Or put differently, how can I transfer a value from one channel to the next in one atomic operation?

I basically want to wait for both ch1 and ch2 to be at a rendezvous point.

Upvotes: 2

Views: 936

Answers (1)

icza
icza

Reputation: 417827

You can't do this with 2 channels. In order to perform a send on ch2, the value to be sent must already be ready, evaluated. Spec: Send statements:

Both the channel and the value expression are evaluated before communication begins.

So even if you would do this, which seemingly does not buffer the value in any variable:

ch2 <- (<- ch1)

Still, the receive from ch1 would be evaluated first, and only then would the send be attempted.

Which means that value must have already been received from ch1. But you can't tell if anyone is "listening" on ch2 (meaning if a send on ch2 could proceed) without attempting to send on ch2 (and even if you could, there is no guarantee that attempting a send after a check there would still be someone listening on it).

Upvotes: 1

Related Questions