package main
import (
"fmt"
)
func main() {
ch4 := make(chan string, 8)
ch5 := make(chan string, 8)
var chs = []chan string{ch4, ch5}
var names = []string{"666", "666", "666"}
select {
case getchan(0, chs) <- getName(2, names):
fmt.Println("执行了第一条语句")
case getchan(1, chs) <- getName(1, names):
fmt.Println("执行了第二条语句")
default:
fmt.Println("默认")
}
ch := make(chan string)
go func() {
for {
ch <- "666"
}
}()
for {
select {
case data := <-ch:
fmt.Println(data)
break
}
fmt.Println("循环中。。。")
}
fmt.Println("main 结束")
}
func getName(i int, name []string) string {
fmt.Printf("name:%d\n", i)
return name[i]
}
func getchan(i int, chs []chan string) chan string {
fmt.Printf("chs: %d\n", i)
return chs[i]
}
详细解释
1. select 语句
select
可以同时监听多个 channel 的读写操作,哪个先准备好就执行哪个 case。- 如果多个 case 都准备好了,会随机选择一个执行。
- 如果没有 case 可用且有
default
,则执行 default
。
2. ch4、ch5、chs、names
ch4
、ch5
:带缓冲的字符串 channel。chs
:channel 数组,方便通过索引访问不同的 channel。names
:字符串数组,全部内容都改成了 "666"
。
3. select 发送数据
getchan(0, chs) <- getName(2, names)
:向第 0 个 channel 发送 names[2]
,即 "666"
。getchan(1, chs) <- getName(1, names)
:向第 1 个 channel 发送 names[1]
,即 "666"
。- 只会执行其中一个 case,并打印对应的提示。
4. for + select 循环
- 新建一个无缓冲 channel
ch
,并启动一个 goroutine 不断向 ch
发送 "666"
。 - 主循环中用
select
读取 ch
,每次收到 "666"
后打印,并继续循环。 break
只跳出 select
,不会跳出 for
,所以会一直循环。
5. getName 和 getchan
getName
:返回 names
数组中指定索引的元素,并打印索引。getchan
:返回 chs
数组中指定索引的 channel,并打印索引。