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

 更新时间:2026年02月05日 09:54:53   作者: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分支最多只能有一个,并且只在无其他可选时执行

含义:

  • default 分支不能有多个;
  • 它只有在所有 case 都阻塞时才会被执行;
  • 不管你把它写在最上面还是最下面,它只有在“无可选分支”时才会被选中。

示例:

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行为规则和执行顺序内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Go语言实战之实现一个简单分布式系统

    Go语言实战之实现一个简单分布式系统

    如今很多云原生系统、分布式系统,例如 Kubernetes,都是用 Go 语言写的,这是因为 Go 语言天然支持异步编程。本篇文章将介绍如何用 Go 语言编写一个简单的分布式系统,需要的小伙伴开业跟随小编一起学习一下
    2022-10-10
  • Go defer 去掉闭包函数及用法分析

    Go defer 去掉闭包函数及用法分析

    这篇文章主要为大家介绍了Go defer 去掉闭包函数及用法分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-07-07
  • golang判断两个事件是否存在冲突的方法示例

    golang判断两个事件是否存在冲突的方法示例

    这篇文章主要为大家详细介绍了golang判断两个事件是否存在冲突的方法示例,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2023-10-10
  • Go语言学习之条件语句使用详解

    Go语言学习之条件语句使用详解

    这篇文章主要介绍了Go语言中条件语句的使用,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-04-04
  • Go语言泛型使用及说明

    Go语言泛型使用及说明

    这篇文章主要介绍了Go语言泛型使用及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2026-01-01
  • 浅析Golang中make和new的用法区别

    浅析Golang中make和new的用法区别

    在Go语言中,有两个比较雷同的内置函数,分别是new和make方法,二者都可以用来分配内存,那他们有什么区别呢?下面就跟随小编一起来学习一下吧
    2024-02-02
  • Go语言中常见的文件操作分享

    Go语言中常见的文件操作分享

    文件操作应该是应用程序里非常常见的一种操作,无论是哪种应用场景,几乎都离不开文件的基本操作。Go语言中提供了三个不同的包去处理文件,下午就来说说它们的具体使用
    2023-01-01
  • golang解析域名的步骤全纪录

    golang解析域名的步骤全纪录

    这篇文章主要给大家介绍了利用golang如何解析域名的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴,下面随着小编来一起学习学习吧
    2018-12-12
  • Golang 锁原理的简单实现

    Golang 锁原理的简单实现

    本文主要介绍了Golang 锁原理的简单实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-03-03
  • Go实现HTTP请求转发的示例代码

    Go实现HTTP请求转发的示例代码

    请求转发是一项核心且常见的功能,本文主要介绍了Go实现HTTP请求转发的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-05-05

最新评论