This is a creation in Article, where the information may have evolved or changed.
The Select Case will eventually be compiled into a compiler,
select { case v, ok = <-c: ... foo default: ... bar} asif c != nil && selectnbrecv2(&v, &ok, c) { ... foo } else { ... bar}
select { case v = <-c: ... foo default: ... bar} asif selectnbrecv(&v, c) { ... foo } else { ... bar}
select { case c <- v: ... foo default: ... bar } asif selectnbsend(c, v) { ... foo } else { ... bar}
We are using select in the above three cases, the compiler will do the corresponding conversion, the above three selectnbsend, SELECTNBRECV, selectnbrecv2 functions are finally called runtime.chansend, RUNTIME.CHANRECV for channel operation Select is an integral part, but it is important to note that select is not executed in case order like switch, such as the following code: "Because the case of select is pseudo-random, That's why the exception is thrown. "
func main() {runtime.GOMAXPROCS(1)int_chan := make(chan int, 1)string_chan := make(chan string, 1)int_chan <- 1string_chan <- "Golang我们走,我们要做好朋友!!!"for {select {case value := <-int_chan:fmt.Println(value)case value := <-string_chan:panic(value) //总会随机到我,我会执行的。。。}}}
It is important to note that although the case is random, the expressions and element expressions in the send or accept statements to the right of all cases keywords are evaluated first, and the Order of evaluation is from top to bottom, from left to right.
In the source code each select corresponds to a hselect structure each hselect structure below has a scase array record each case, in Scase records the structure of C Hchan is the column of the previous article channel structure Pollorder Scase the elements from the new arrangement.
func main() {runtime.GOMAXPROCS(1)int_chan := make(chan int, 1)select {default:fmt.Println("default...")case value := <-int_chan:fmt.Println(value)}}
Finally, it is also stated that the position of default and case in select does not affect the rules of branch selection.