package main
import (
"fmt"
)
func main() {
ch1 := make(chan int)
ch2 := make(chan int)
go func() {
for i := 0; i < 5; i++ {
ch1 <- i
}
close(ch1)
}()
go func() {
for i := 0; i < 3; i++ {
ch2 <- i * 2
}
close(ch2)
}()
for {
select {
case data, ok := <-ch1:
if!ok {
return
}
fmt.Printf("Received from ch1: %d\n", data)
case data, ok := <-ch2:
if!ok {
return
}
fmt.Printf("Received from ch2: %d\n", data)
}
}
}
select语句在循环中的作用
- 多路监听:
select
语句可以同时监听多个通道的操作(这里是ch1
和ch2
),当任意一个通道有数据可读(或可写,在其他场景下)时,对应的case
分支会被执行。
- 阻塞等待:在
for
循环内,select
语句处于阻塞状态,直到有通道操作准备好。这意味着程序不会继续执行select
之后的代码,而是等待通道上的事件发生。
- 公平性:当多个通道同时准备好时,
select
会随机选择一个case
分支执行,保证每个通道都有平等的机会被处理。
- 检测通道关闭:通过
ok
变量(如data, ok := <-ch1
),可以检测通道是否关闭。当通道关闭且没有数据可读时,ok
为false
,此时可以结束程序,避免无效读取。