https://play.golang.org/p/FMKxtVlTL5
为什么select语句中的default:
无限循环程序?
package main
import (
"fmt"
"strconv"
"time"
)
var quit chan bool
var counter chan int
func main() {
counter = make(chan int)
quit = make(chan bool)
go func() {
i := 0
for {
i++
select {
case <-quit:
fmt.Println("Bye!")
return
case counter <- i:
fmt.Println("Send! " + strconv.Itoa(i))
default:
fmt.Println("Default! " + strconv.Itoa(i))
}
}
}()
fmt.Println("Receive! " + strconv.Itoa(<-counter))
fmt.Println("Receive! " + strconv.Itoa(<-counter))
fmt.Println("Receive! " + strconv.Itoa(<-counter))
fmt.Println("Receive! " + strconv.Itoa(<-counter))
fmt.Println("Receive! " + strconv.Itoa(<-counter))
fmt.Println("Receive! " + strconv.Itoa(<-counter))
quit <- true
time.Sleep(1 * time.Second)
}
答案 0 :(得分:6)
当select
有default
时,它会变为非阻塞状态。引用规范:
如果一个或多个通信可以继续,则可以通过统一的伪随机选择来选择可以继续的单个通信。否则,如果存在默认情况,则选择该情况。如果没有默认情况,&#34;选择&#34;语句阻塞,直到至少有一个通信可以继续。
如果没有default
,select
会等到它可以从quit
接收或发送counter
,然后继续(通过for
1}}再次循环,除非它运行return
)。 使用默认值,select
永远不会等待任何内容,default
只会在每次运行时运行,除非其他操作之一通过。
理论上程序仍然有效,并且会在第六次打印后退出&#34;发送!&#34;和&#34;接收!&#34; - 但它可能太忙了打印&#34;默认!&#34;几十亿次在合理的时间内到达那里。