写点什么

Go 语言入门 15—select

作者:良猿
  • 2022-11-08
    湖北
  • 本文字数:1510 字

    阅读完需:约 5 分钟

Go语言入门15—select

select

select 是 go 语言中的一种条件控制语句,类似于之前学习的 switch 条件控制语句,不同的是 select 只能用于通道的控制,在 select 中同样可以有多个 case 分支和一个 default 分支,但是每一个 case 必须都是 channel 的操作,可以是发送也可以是接收,select 会一直等待,直到某一个 case 分支的 channel 操作完成之后就执行对应的代码语句。


基本语法:


select {    case channel 语句 1 :       // 匹配到 channel 语句 1 则执行该内容    case channel 语句 2 :       // 匹配到 channel 语句 1 则执行该内容    default :  // 默认执行       // default 内容}
复制代码


select 同时监听多个分支,一直堵塞直到其中一个分支完成 channel


代码示例:


package main
import ( "fmt")
func main() { intChan := make(chan int) stringChan := make(chan string)
go func(ch chan int) { time.Sleep(time.Second * 2) ch <- 1 }(intChan)
go func(ch chan string) { time.Sleep(time.Second) ch <- "a" }(stringChan)
select { case i := <- intChan: // 监听 intChan 的操作 fmt.Println(i) case s := <- stringChan: // 监听 stringChan 的操作 fmt.Println(s) }}
复制代码


上述代码中的 select 有两个 case 分支,分别监听了 intChan 和 stringChan 两个通道,然后在程序中启动两个 goroutine 分别对这两个通道发送数据,则 select 会一直堵塞,直到其中一个 case 的 channel 接收到数据就执行其对应的输出语句,由于在往 intChan 中发送数据之前有两秒钟的睡眠时间, stringChan 只有一秒钟的睡眠时间,所以当前代码中永远都是 stringChan 先好,最后的结果则是在控制台打印字母 a。


在 select 中增加 default 语句后则不会一直堵塞等待


代码示例:


select {    case i := <- intChan:        fmt.Println(i)    case s := <-stringChan:        fmt.Println(s)    default:        fmt.Println("default操作")}
复制代码


在保持上面代码都不变的情况下,仅在 select 语句的最后加入一个 default 分支,这样再次运行代码就会打印输出 default操作,这是因为在 select 语句中加入 default 之后就不会堵塞等待,而且在 intChan 和 stringChan 中分别有一秒和两秒的沉睡,当执行到 select 语句时,两个 channel 都没有准备好,就会直接执行 default 分支的内容。


当多个 channel 同时准备好时,随机执行其中一个


代码示例:


package main
import ( "fmt" "time")
func main() { intChan := make(chan int) stringChan := make(chan string)
go func(ch chan int) { ch <- 1 }(intChan)
go func(ch chan string) { ch <- "a" }(stringChan)
time.Sleep(time.Second) // 睡眠一秒钟,确保两个 channel 都准备好
select { case i := <- intChan: fmt.Println(i) case s := <-stringChan: fmt.Println(s) }}
复制代码


上面的代码中,在 select 语句之前睡眠了一秒钟,用于确保前面两个 goroutine 都执行完毕并把数据发送到 channel 中,然后再执行后面的 select 语句,这时候执行到 select 语句时,intChan 和 stringChan 都是准备就绪状态,则这时候 select 会随机选择一个 case 分支执行,所以在最后的输出结果中会随机在控制台打印数字 1 或者字母 a。


select 总结:


  1. 每一个 case 都必须是一个通道操作。

  2. 没有 default 分支时,select 会堵塞,有 default 分支时直接执行 default 分支内容。

  3. 如果有多个 case 分支同时准备就绪,则随机执行其中一个,其他的则忽略。


发布于: 刚刚阅读数: 2
用户头像

良猿

关注

还未添加个人签名 2019-02-13 加入

还未添加个人简介

评论

发布
暂无评论
Go语言入门15—select_Go_良猿_InfoQ写作社区