前言
select是go中的一个控制结构,每个case必须是通道操作,select会随机选择一个case执行操作,可以用它执行进行阻塞操作
select使用
select语句使用如下例子
package main
import (
"fmt"
"time"
)
func main() {
a := make(chan int64)
go func() {
fmt.Println("===================11执行开始")
time.Sleep(3 * time.Second)
fmt.Println("===================11执行结束")
a <- 1
}()
select {
case <-time.After(2 * time.Second):
fmt.Println("=============超时")
case <-a:
fmt.Println("==========执行结束")
}
}
以下输出结果如下
因为
chan没有在2秒内执行结束,所以会执行
case <-time.After(2 * time.Second)
这个操作
default语句
select提供default语句,表示如果所有case没有执行的时候,就执行default
package main
import (
"fmt"
"time"
)
func main() {
a := make(chan int64)
go func() {
fmt.Println("===================11执行开始")
time.Sleep(3 * time.Second)
fmt.Println("===================11执行结束")
a <- 1
}()
select {
case <-time.After(2 * time.Second):
fmt.Println("=============超时")
return
case <-a:
fmt.Println("==========执行结束")
return
default:
fmt.Println("==============执行默认")
}
}
执行结果如下
如果有多个
select语句要执行,如果没有default语句,则默认会阻塞
package main
import (
"fmt"
"time"
)
func main() {
a := make(chan int64)
b := make(chan int64)
go func() {
fmt.Println("===================11执行开始")
time.Sleep(3 * time.Second)
fmt.Println("===================11执行结束")
a <- 1
}()
go func() {
fmt.Println("===================22执行开始")
time.Sleep(4 * time.Second)
fmt.Println("===================22执行结束")
b <- 2
}()
for i := 0; i < 2; i++ {
select {
case <-b:
fmt.Println("==========执行结束")
case <-a:
fmt.Println("==========执行结束")
}
}
}
执行结果会按照顺序打印
可以使用
for循环从两个通道获取数据
package main
import (
"fmt"
"time"
)
func main() {
a := make(chan int64)
go func() {
fmt.Println("===================11执行开始")
time.Sleep(3 * time.Second)
fmt.Println("===================11执行结束")
a <- 1
}()
for {
select {
case <-a:
fmt.Println("==========执行a结束")
default:
fmt.Println("=========================执行default")
}
}
}
如果要终止无限循环,则可以在case中加个return
case <-a:
fmt.Println("==========执行a结束")
return
总结
select语句可以帮助处理很多情况,比如程序超时问题等,可以更好利用它