问题1:下面代码输出什么
package mainimport ("fmt""time"
)func main() {// 创建两个定时器,一个间隔为1秒,另一个间隔为2秒ticker1 := time.NewTicker(1 * time.Second)ticker2 := time.NewTicker(2 * time.Second)// 在一个新的 goroutine 中运行监听逻辑go func() {for {select {case t1 := <-ticker1.C:fmt.Println("1s ticker:", t1)case t2 := <-ticker2.C:fmt.Println("2s ticker:", t2)default:fmt.Println("default")}}}()// 主函数运行一段时间time.Sleep(5 * time.Second)fmt.Println("Done")
}
问题2:如果加上一行代码呢
package mainimport ("fmt""time"
)func main() {// 创建两个定时器,一个间隔为1秒,另一个间隔为2秒ticker1 := time.NewTicker(1 * time.Second)ticker2 := time.NewTicker(2 * time.Second)// 在一个新的 goroutine 中运行监听逻辑go func() {for {select {case t1 := <-ticker1.C:fmt.Println("1s ticker:", t1)case t2 := <-ticker2.C:fmt.Println("2s ticker:", t2)default:fmt.Println("default")time.Sleep(1 * time.Second)}}}()// 主函数运行一段时间time.Sleep(5 * time.Second)fmt.Println("Done")
}
问题1的答案是会一直输出default,直到5s结束
问题2的答案是
default
1s ticker: 2024-11-13 13:37:09.5503567 +0800 CST m=+1.000307501
default
2s ticker: 2024-11-13 13:37:10.5503405 +0800 CST m=+2.000307501
1s ticker: 2024-11-13 13:37:10.5503405 +0800 CST m=+2.000307501
default
1s ticker: 2024-11-13 13:37:11.5503246 +0800 CST m=+3.000307501
default
2s ticker: 2024-11-13 13:37:12.5503087 +0800 CST m=+4.000307501
1s ticker: 2024-11-13 13:37:12.5503087 +0800 CST m=+4.000307501
default
Done
原因
select 语句中的 default 情况会执行是因为 select 语句默认会阻塞,直到其监听的通道中有数据可读。
如果没有通道准备好,select 就不会进入任何一个 case,而是继续阻塞等待。
default 分支没有被设计为在特定条件下退出循环,因此它会不断地打印 "default"