Go

What does this select print, and where does the break go?

Question 497MediumGo 1.22 to 1.25
a := make(chan int, 1)
b := make(chan int, 1)
a <- 1
b <- 2
select {
case v := <-a:
    fmt.Println("a", v)
case v := <-b:
    fmt.Println("b", v)
}

ticker := time.NewTicker(10 * time.Millisecond)
defer ticker.Stop()
done := time.After(50 * time.Millisecond)
for {
    select {
    case <-ticker.C:
        fmt.Println("tick")
    case <-done:
        fmt.Println("done")
        break // BUG: only exits the select
    }
}

The first select prints either a 1 or b 2. When several cases are ready, Go picks one uniformly at random. Source order gives no priority, which prevents starvation. If you need priority, check the high-priority channel in its own non-blocking select first.

In the second part, break inside select (or switch) ends only the select. The for loop keeps going, prints "tick" forever, and never leaves after "done". Fix it with a label, or return:

loop:
    for {
        select {
        case <-ticker.C:
            fmt.Println("tick")
        case <-done:
            fmt.Println("done")
            break loop
        }
    }

More on Tricky Output & Code-Review Puzzles

All 38 Tricky Output & Code-Review Puzzles questions