Golang

关注公众号 jb51net

关闭
首页 > 脚本专栏 > Golang > Go select行为规则和执行顺序

Go中select行为规则和执行顺序的实现

作者:Kevin666

Go语言中的select语句用于在多个通信操作中进行选择,本文就来详细的介绍一下Go中select行为规则和执行顺序的实现,具有一定的参考价值,感兴趣的可以了解一下

Go 语言中 select 语句的行为规则和执行顺序。

✅ 规则1:每个case表达式必须有发送或接收操作,可能还有其他表达式

含义:

每个 case 至少要有一个通道操作(<-chan 或 chan<-),可以搭配赋值、函数调用等。

示例:

ch := make(chan int, 1)

select {
case x := <-ch: // 接收操作 + 赋值
	fmt.Println("Received:", x)
}
select {
case ch <- computeValue(): // 发送操作 + 函数调用
	fmt.Println("Sent")
}

✅ 规则2:表达式求值顺序是从上到下,从左到右

含义:

所有 case 分支中的表达式,在 select 执行之初就按书写顺序全部求值。表达式多于一个时,按从左到右顺序求值。

示例:

ch1 := make(chan int)
ch2 := make(chan int)

select {
case x := <-ch1:
	fmt.Println("ch1", x)
case y := <-ch2:
	fmt.Println("ch2", y)
}

上面例子中:

  1. ch1 的接收表达式会先被求值;
  2. 然后 ch2;
  3. 然后再看哪个能成功进行选择。

✅ 规则3:如果通道操作阻塞,case 就不满足条件

含义:

当某个 case 执行通道操作时,如果它会阻塞(比如通道没数据,或者通道满) ,它就不能被选中。

示例:

ch := make(chan int)

select {
case ch <- 1: // 没有接收方,发送会阻塞
	fmt.Println("sent")
default:
	fmt.Println("default")
}

输出:

default

✅ 规则4:只有所有 case 表达式求值完后,select 才选分支

含义:

select 要先静态地评估所有分支是否能执行,然后才在满足条件的分支中挑选一个。

示例:

ch := make(chan int, 1)
ch <- 42

select {
case x := <-ch: // 可执行
	fmt.Println("got", x)
case y := <-ch: // 不可执行(通道空了)
	fmt.Println("got", y)
}

输出:

got 42

✅ 规则5:多个可选分支时,select 随机选一个

含义:

多个分支都可执行时,select 不会按照书写顺序选第一个,而是随机选一个。

示例:

ch1 := make(chan int, 1)
ch2 := make(chan int, 1)
ch1 <- 1
ch2 <- 2

select {
case x := <-ch1:
	fmt.Println("ch1", x)
case y := <-ch2:
	fmt.Println("ch2", y)
}

输出可能是:

ch1 1

或者

ch2 2

✅ 规则6:default分支最多只能有一个,并且只在无其他可选时执行

含义:

示例:

ch := make(chan int)

select {
default:
	fmt.Println("default executed")
case <-ch:
	fmt.Println("received")
}

输出:

default executed

小结

场景描述是否满足选择条件
通道有数据可读(接收操作)
通道有空位可写(发送操作)
通道阻塞(接收或发送都不能继续)
所有 case 都阻塞 + 有 default选中 default
所有 case 都阻塞 + 无 defaultselect 阻塞
多个 case 都满足条件随机选一个

到此这篇关于Go中select行为规则和执行顺序的实现的文章就介绍到这了,更多相关Go select行为规则和执行顺序内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文