The for-select Loop
golang concurrency for-select
The for-select loop helps a lot in
- Iterating something into a channel
- Infinite loop until we tell it to stop
This example uses 2 channels, data is for sending/receiving data, done is the channel to signal the data iteration to stop in certain condition.
func IterateToChannel() { data := make(chan string) done := make(chan interface{}) go func() { for v := range data { fmt.Print(v, " ") // Stop the DATA_LOOP if the value is a integer if _, err := strconv.Atoi(v); err == nil { close(done) } } }() DATA_LOOP: for _, v := range []string{"a", "b", "1", "c"} { select { case <-done: break DATA_LOOP // return case data <- v: } } }
The code prints a b 1 and stops.
Notice that in the above sample code, we can use the default case to write the incoming string to the channel data until the done channel is closed and stop the DATA_LOOP.
DATA_LOOP: for _, v := range []string{"a", "b", "1", "c"} { select { case <-done: break DATA_LOOP default: data <- v } }
Or do nothing in the default case and exit the select block.
DATA_LOOP: for _, v := range []string{"a", "b", "1", "c"} { select { case <-done: break DATA_LOOP default: } data <- v }
This example creates a infinite loop to print current time, but the loop will only run 5 times.
func InfiniteLoopThatCanStop() { const max int = 5 counter := 0 done := make(chan interface{}) LOOP: for { select { case <-done: break LOOP case <-time.After(1 * time.Second): if counter >= max { fmt.Println("Time's up") close(done) } else { // Print the current time in GMT format fmt.Println(time.Now().UTC().Format(http.TimeFormat)) counter++ } } } }
沒有留言:
張貼留言