I'm trying to use a select
in a loop to receive either a message or a timeout signal. If the timeout signal is received, the loop should abort:
package main import ("fmt"; "time") func main() { done := time.After(1*time.Millisecond) numbers := make(chan int) go func() {for n:=0;; {numbers <- n; n++}}() for { select { case <-done: break case num := <- numbers: fmt.Println(num) } } }
However, it doesn't seem to be stopping:
$ go run a.go 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 [...] 3824 3825 [...]
Why? Am I using time.After
wrong?
A "break" statement terminates execution of the innermost "for", "switch", or "select" statement within the same function. In your example you're just breaking out of the select statement. If you replace break with a return statement you will see that it's working.
break. The break statement is used to terminate the for loop abruptly before it finishes its normal execution and move the control to the line of code just after the for loop. Let's write a program that prints numbers from 1 to 5 using break.
break terminates the execution of a for or while loop. Statements in the loop after the break statement do not execute. In nested loops, break exits only from the loop in which it occurs. Control passes to the statement that follows the end of that loop.
The break statement is used to terminate the loop or statement in which it presents. After that, the control will pass to the statements that present after the break statement, if available. If the break statement present in the nested loop, then it terminates only those loops which contains break statement.
The Go spec says:
A "break" statement terminates execution of the innermost "for", "switch", or "select" statement within the same function.
In your example you're just breaking out of the select statement. If you replace break
with a return
statement you will see that it's working.
The "Go" way for that kind of situations is to use labels and break on the label, for example:
L: for { select { case <-done: break L case num := <- numbers: fmt.Println(num) } }
Ref:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With