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

相关文章

  • Golang并发编程深入分析

    Golang并发编程深入分析

    golang中的并发,是函数相互独立运行的能力,goroutines是并发运行的函数。golang提供了goroutines作为并发处理的一种方式
    2022-11-11
  • Go语言中map集合的具体使用

    Go语言中map集合的具体使用

    本文主要介绍了Go语言中map集合的具体使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-02-02
  • golang实现sql结果集以json格式输出的方法

    golang实现sql结果集以json格式输出的方法

    这篇文章主要介绍了golang实现sql结果集以json格式输出的方法,涉及Go语言针对sql结果集的遍历、转换及json格式相关操作技巧,需要的朋友可以参考下
    2017-03-03
  • Go语言Select chan用法小结

    Go语言Select chan用法小结

    select语句是Go语言中用于处理多个通道操作的关键字,它允许你在多个通道上进行非阻塞的选择操作,本文就详细介绍一下如何使用,感兴趣的可以了解一下
    2023-09-09
  • 优雅管理Go Project生命周期

    优雅管理Go Project生命周期

    这篇文章主要为大家介绍了如何优雅的管理Go Project生命周期,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-03-03
  • Go语言基于Goroutine的超时控制方案设计与实践

    Go语言基于Goroutine的超时控制方案设计与实践

    Go语言因其并发特性而备受青睐,尤其是goroutine和channel的组合,像一对默契的搭档,为开发者提供了轻量、高效的并发工具,下面我们来看看基于goroutine的超时控制方案吧
    2025-05-05
  • Go语言接口与多态详细介绍

    Go语言接口与多态详细介绍

    Go语言的接口类型是一组方法定义的集合,它体现了多态性、高内聚和低耦合的设计思想,接口通过interface关键字定义,无需实现具体方法,任何实现了接口所有方法的类型即视为实现了该接口,感兴趣的朋友一起看看吧
    2024-09-09
  • Go语言流程控制详情

    Go语言流程控制详情

    这篇文章主要介绍了Go语言流程控制详情,流程控制包含分三大类:条件判断,循环控制和无条件跳转。下面关于更多相关内容需要的小伙伴可以参考一下
    2022-03-03
  • 深入解析Sync.Pool如何提升Go程序性能

    深入解析Sync.Pool如何提升Go程序性能

    在并发编程中,资源的分配和回收是一个很重要的问题。Go 语言的 Sync.Pool 是一个可以帮助我们优化这个问题的工具。本篇文章将会介绍 Sync.Pool 的用法、原理以及如何在项目中正确使用它,希望对大家有所帮助
    2023-05-05
  • Go打包附件内容到执行文件的方法

    Go打包附件内容到执行文件的方法

    处于种种原因, 我们不希望这部分额外的内容以附件的形式出现, 有没有什么办法能够将附件内容直接打包进可执行文件中呢,下面小编给大家介绍下Go打包附件内容到执行文件的方法,感兴趣的朋友一起看看吧
    2023-03-03

最新评论