作者:月亮哥哥是团宠他男人 | 来源:互联网 | 2023-07-03 10:41
概述select类似switch,包含一系列逻辑分支和一个可选的默认分支。每一个分支对应通道上的一次操作(发送或接收),可以将select理解为专门针对通道操作的switch语句。
概述
select
类似 switch
, 包含一系列逻辑分支和一个可选的默认分支。每一个分支对应通道上的一次操作 (发送或接收),
可以将 select
理解为专门针对通道操作的 switch
语句。
语法规则
select {
case v1 := <- ch1:
case v2 := <- ch2:
default:
}
执行顺序
- 当同时存在多个满足条件的通道时,随机选择一个执行
- 如果没有满足条件的通道时,检测是否存在 default 分支
通常情况下,把含有 default 分支
的 select
操作称为 无阻塞通道操作
。
例子
随机执行一个
package main
import (
"fmt"
"time"
)
func main() {
ch1 := make(chan string)
ch2 := make(chan string)
done := make(chan bool)
go func() {
ch1 <- "hello"
}()
go func() {
ch2 <- "world"
}()
go func() {
done <- true
}()
time.Sleep(time.Second)
select {
case msg := <-ch1:
fmt.Printf("ch1 msg = %s\n", msg)
case msg := <-ch2:
fmt.Printf("ch2 msg = %s\n", msg)
case <-done:
fmt.Println("done !")
}
close(ch1)
close(ch2)
close(done)
}
default (无阻塞通道操作)
package main
import (
"fmt"
"time"
)
func main() {
ch1 := make(chan string)
ch2 := make(chan string)
done := make(chan bool)
go func() {
time.Sleep(time.Second)
ch1 <- "hello"
}()
go func() {
time.Sleep(time.Second)
ch2 <- "world"
}()
go func() {
time.Sleep(time.Second)
done <- true
}()
select {
case msg := <-ch1:
fmt.Printf("ch1 msg = %s\n", msg)
case msg := <-ch2:
fmt.Printf("ch2 msg = %s\n", msg)
case <-done:
fmt.Println("done !")
default:
fmt.Println("default !")
}
close(ch1)
close(ch2)
close(done)
}
和 for 搭配使用
通过在 select
外层加一个 for
循环,可以达到 无限轮询
的效果。
package main
import (
"fmt"
"time"
)
func main() {
ch1 := make(chan string)
ch2 := make(chan string)
done := make(chan bool)
go func() {
fmt.Println("[ch1 goroutine]")
time.Sleep(time.Second)
ch1 <- "hello"
}()
go func() {
for i := 0; i < 2; i++ {
fmt.Println("[ch2 goroutine]")
time.Sleep(time.Second)
}
ch2 <- "world"
}()
go func() {
for i := 0; i < 3; i++ {
fmt.Println("[done goroutine]")
time.Sleep(time.Second)
}
done <- true
}()
for exit := true; exit; {
select {
case msg := <-ch1:
fmt.Printf("ch1 msg = %s\n", msg)
case msg := <-ch2:
fmt.Printf("ch2 msg = %s\n", msg)
case <-done:
fmt.Println("done !")
exit = false
}
}
close(ch1)
close(ch2)
close(done)
}
从输出结果看,[ch1 goroutine]
输出了 1 次,[ch2 goroutine]
输出了 2 次,[done goroutine]
输出了 3 次。
联系我
![公众号](https://img6.php1.cn/3cdc5/c64b/807/2d2937c55727f0c5.png)
go