Table of Contents
- Select Hints
Select Hints
A “select” statement chooses which of a set of possible send or receive operations will proceed.
If one or more of the communications can proceed, a single one that can proceed is chosen via a uniform pseudo-random selection. Otherwise, if there is a default case, that case is chosen. If there is no default case, the “select” statement blocks until at least one of the communications can proceed.
-
If multiple cases are ready, one is chosen at random.
package main
import (
"fmt"
"time"
)
func main() {
a := make(chan string)
b := make(chan string)
go func() {
time.Sleep(100 * time.Millisecond)
a <- "你好,世界"
}()
go func() {
time.Sleep(100 * time.Millisecond)
b <- "Hello World"
}()
select {
case data1 := <-a:
fmt.Println("got", data1) // may select
case data2 := <-b:
fmt.Println("got", data2) // may select
}
}
-
The default case executes if no other case is ready, avoiding a block.
package main
import (
"fmt"
)
func main() {
ch1 := make(chan string)
ch2 := make(chan string)
select {
case msg1 := <-ch1: // no sender produce data , block
fmt.Println(msg1)
case msg2 := <-ch2: // no sender produce data , block
fmt.Println(msg2)
default: // select
fmt.Println("No cases are ready yet")
}
}
-
Select blocks until at least one channel operation is ready.
The following program will cause a deadlock as no cases are satisfied.
package main
import (
"fmt"
)
func main() {
ch1 := make(chan string)
ch2 := make(chan string)
select {
case msg1 := <-ch1: // no sender produce data , block
fmt.Println(msg1)
case msg2 := <-ch2: // no sender produce data , block
fmt.Println(msg2)
}
}
-
Select never selects a blocking case.
Sends and receives on nil channels block. Select never selects a blocking case.
package main
import (
"fmt"
"math/rand"
)
func main() {
a, b := make(chan string), make(chan string)
go func() { a <- "a" }()
go func() { b <- "b" }()
if rand.Intn(2) == 0 {
a = nil
fmt.Println("nil a")
} else {
b = nil
fmt.Println("nil b")
}
select {
case s := <-a:
fmt.Println("got", s)
case s := <-b:
fmt.Println("got", s)
}
}