首页 > 技术文章 > GO之select语句

pebblecome 2021-01-28 18:16 原文

Go 语言中的 select语句用于监控并选择一组case语句执行相应的代码。它看起来类似于switch语句,但是select语句中所有case中的表达式都必须是channel的发送或接收操作。一个典型的select使用示例如下:

select {
case <-ch1:
	fmt.Println("xxx.com")
case ch2 <- 1:
	fmt.Println("xiaoman")
}

  

Go 语言中的 select 关键字也能够让当前 goroutine 同时等待ch1 的可读和ch2的可写,在ch1ch2状态改变之前,select 会一直阻塞下去,直到其中的一个 channel 转为就绪状态时执行对应case分支的代码。如果多个channel同时就绪的话则随机选择一个case执行。

除了上面展示的典型示例外,接下来我们逐一介绍一些select的特殊示例。

空select

select指的是内部不包含任何case,例如:

select{
  
}

  

空的 select 语句会直接阻塞当前的goroutine,使得该goroutine进入无法被唤醒的永久休眠状态。

只有一个case

如果select中只包含一个case,那么该select就变成了一个阻塞的channel读/写操作。

select {
case <-ch1:
	fmt.Println("xxxx.com")
}

  

上面的代码,当ch1可读时会执行打印操作,否则就会阻塞。

有default语句

如果select中还可以包含default语句,用于当其他case都不满足时执行一些默认操作。

select {
case <-ch1:
	fmt.Println("xxx.com")
default:
	time.Sleep(time.Second)
}

  

上面的代码,当ch1可读时会执行打印操作,否则就执行default语句中的代码,这里就相当于做了一个非阻塞的channel读取操作。

最后总结一下:

  • select 不存在任何的 case:永久阻塞当前 goroutine
  • select 只存在一个 case:阻塞的发送/接收
  • select 存在多个 case:随机选择一个满足条件的case执行
  • select 存在 default,其他case都不满足时:执行default语句中的代码

推荐阅读