用法
- select 语句只能用于管道操作,即 从管道中接受或者是传输进管道中
- select 语句会监听所有指定的通道上的操作,一旦其中一个管道准备好时,会执行相应的代码语句
- 如果有多个通道都准备好了,那么select语句会随机选择执行一个通道执行
- 如果所有的 通道都没有准备好,那么会执行default语句(有default语句的情形下)
package main
import "fmt"
func main() {
// 定义两个通道
ch1 := make(chan string)
ch2 := make(chan string)
// 启动两个 goroutine,分别从两个通道中获取数据
go func() {
for {
ch1 <- "from 1"
}
}()
go func() {
for {
ch2 <- "from 2"
}
}()
// 使用 select 语句非阻塞地从两个通道中获取数据
for {
select {
case msg1 := <-ch1:
fmt.Println(msg1)
case msg2 := <-ch2:
fmt.Println(msg2)
default:
// 如果两个通道都没有可用的数据,则执行这里的语句
fmt.Println("no message received")
}
}
}
time.After(time.second*1)
上面已经提到select语句只能用于管道操作,而 time.After的返回值就是 <-chan time
package main
import (
"fmt"
"time"
)
func main() {
c1 := make(chan string, 1)
go func() {
time.Sleep(2 * time.Second)
c1 <- "result 1"
}()
select {
case <-time.After(1 * time.Second):
fmt.Println("time out 1")
case res := <-c1:
fmt.Println(res)
}
c2 := make(chan string, 1)
go func() {
c2 <- "result 2"
}()
select {
case <-time.After(3 * time.Second):
fmt.Println("time out 3")
case res := <-c2:
fmt.Println(res)
}
}
default
package main
import "fmt"
func main() {
messages := make(chan string)
signals := make(chan bool)
select {
case msg := <-messages:
fmt.Println("received message", msg)
default:
fmt.Println("no message received")
}
msg := "hi"
select {
case messages <- msg:
fmt.Println("sent message", msg)
default:
fmt.Println("no message sent")
}
select {
case msg := <-messages:
fmt.Println("received message", msg)
case sig := <-signals:
fmt.Println("received signal", sig)
default:
fmt.Println("no activity")
}
}