Wrong Code Example for Mistake 64 (Expecting a deterministic behavior using select and channels)
Author: gatogato999Created Mar 29, 2026Updated Mar 29, 2026
Labelscommunity mistake
Describe the mistake
In the description of "Expecting a deterministic behavior using select and channels (64)" , its written that the output of the code will be random :
0
1
2
disconnection, return
# or
0
disconnection, return- But here, that situation doesn't arise because the disconnect send happens strictly after all message sends.
- the true output is not random , its always :
0
1
2
3
4
5
6
7
8
9
disconnection, return- you will see the numbers 0–9 printed (in order), then "disconnection, return", and the program exits.
- the code snippet shows a goroutine that does two things in sequence:
- Sends integers 0 through 9 into
messageCh - After the loop finishes, sends a signal into
disconnectCh
Meanwhile, the main loop continuously runs a select with two cases:
- receive from
messageCh - receive from
disconnectCh - Key detail: ordering guarantee
- Inside the goroutine, this part is strictly sequential:
- All
messageCh <- isends happen first - Only after the loop completes does
disconnectCh <- struct{}{}run
So the disconnect signal cannot happen before all numbers are sent.
- What the select does
- Pick
messageChwhenever a value is available - Eventually pick
disconnectChonce that signal is sent
Because the disconnect happens after all sends, the loop will first consume all numbers.
Solution
Make the output non-deterministic
- Right now, the code is deterministic because:
- One goroutine sends values in order
disconnectChonly fires after all sends finish
- To make it “random”, you need multiple competing producers or race between channels.
- Example: multiple goroutines sending
for i := 0; i < 10; i++ {
go func(n int) {
messageCh <- n
}(i)
}
go func() {
// give time for sends to race
time.Sleep(time.Millisecond * 10)
disconnectCh <- struct{}{}
}()
for {
select {
case v := <-messageCh:
fmt.Println(v)
case <-disconnectCh:
fmt.Println("disconnection, return")
return
}
}What changes?
- Now 10 goroutines are sending concurrently
- Order becomes non-deterministic
Source: teivah/100-go-mistakes