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

作者:

文章目录
  • 场景描述 是否满足选择条件 通道有数据可读(接收操作) ✅ 通道有空位可写(发送操作) ✅ 通道阻塞(接收或发送都不能继续) ❌ 所有 case 都阻塞 + 有 default 选中 default 所有 case 都阻塞 + 无 default select 阻塞 多个 case 都满足条件 随机选一个 到此这篇关于Go中select行为规则和执行顺序的实现的文章就介绍到这了,更多相关Go select行为规则和执行顺序内容请搜索风君子博客以前的文章或继续浏览下面的相关文章希望大家以后多多支持风君子博客! 您可能感兴趣的文章: Go语言中Select语句用法实例 Golang中switch语句和select语句的用法教程 Go语言使用select{}阻塞main函数介绍 golang中的select关键字用法总结 Golang的select多路复用及channel使用操作 Go语言面试题之select和channel的用法
  • 目录
    • ✅ 规则1:每个case表达式必须有发送或接收操作,可能还有其他表达式
      • 含义:
      • 示例:
    • ✅ 规则2:表达式求值顺序是从上到下,从左到右
      • 含义:
      • 示例:
    • ✅ 规则3:如果通道操作阻塞,case 就不满足条件
      • 含义:
      • 示例:
    • ✅ 规则4:只有所有 case 表达式求值完后,select 才选分支
      • 含义:
      • 示例:
    • ✅ 规则5:多个可选分支时,select 随机选一个
      • 含义:
      • 示例:
    • ✅ 规则6:default分支最多只能有一个,并且只在无其他可选时执行
      • 含义:
      • 示例:
    • 小结

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

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

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

      所有 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. 然后再看哪个能成功进行选择。

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

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

      输出:

      default

      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

      多个分支都可执行时,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

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

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

      输出:

      default executed

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

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

      您可能感兴趣的文章:

      • Go语言中Select语句用法实例
      • Golang中switch语句和select语句的用法教程
      • Go语言使用select{}阻塞main函数介绍
      • golang中的select关键字用法总结
      • Golang的select多路复用及channel使用操作
      • Go语言面试题之select和channel的用法

      站内搜索