Why this Golang code is not chosen between several points. After the channels work?

Why is this Golang code not choosing between several points. After the channels work?

See code below. The message "Timeout" is never issued. Why?

package main import ( "fmt" "time" ) func main() { count := 0 for { select { case <-time.After(1 * time.Second): count++ fmt.Printf("tick %d\n", count) if count >= 5 { fmt.Printf("ugh\n") return } case <-time.After(3 * time.Second): fmt.Printf("timeout\n") return } } } 

Launch it on the playground: http://play.golang.org/p/1gku-CWVAh

Output:

 tick 1 tick 2 tick 3 tick 4 tick 5 ugh 
+6
source share
2 answers

Because time.After is a function, so at each iteration it returns a new channel. If you want this channel to be the same for all iterations, you must save it before the loop:

 timeout := time.After(3 * time.Second) for { select { //... case <-timeout: fmt.Printf("timeout\n") return } } 

Playground: http://play.golang.org/p/muWLgTxpNf .

+11
source

Even @ Ainar-G already provided the answer, another possibility is to use time.Tick(1e9) to generate a timestamp every second, and then listen to timeAfter after the specified period.

 package main import ( "fmt" "time" ) func main() { count := 0 timeTick := time.Tick(1 * time.Second) timeAfter := time.After(5 * time.Second) for { select { case <-timeTick: count++ fmt.Printf("tick %d\n", count) if count >= 5 { fmt.Printf("ugh\n") return } case <-timeAfter: fmt.Printf("timeout\n") return } } } 
+3
source

All Articles