关于go中的select

笔记仓库:gitee.com/xiaoyinhui


代码中的解释纯个人理解,有不对的望指出

go 复制代码
package tests

import (
	"fmt"
	"testing"
)

var uCnt int = 0

func TestSelece(t *testing.T) {
	// 对于 select 语句,在进入该语句时,会按源码的顺序对每一个 case 子句进行求值:这个求值只针对发送或接收操作的额外表达式

	/*
		根据下面【select01()】的输出结果 可以分析出来【对于 select 语句,在进入该语句时,会按源码的顺序对每一个 case 子句进行求值】的意思

			可以看到每次遍历都会计算出3次方法 showStr 的结果,直白点讲就是会执行一次这个方法
			并且 还是按照代码的顺序 123 进行顺序执行的
			至于选择那个进行执行这就没有办法确定,因为都可以执行,选择那个执行得看底层的选择
	*/
	select01()

	fmt.Println("")
	fmt.Println("******************************************")
	fmt.Println("******************************************")
	fmt.Println("")

	/*
		根据下面【select02()】的输出结果 可以分析出来【这个求值只针对发送或接收操作的额外表达式】的意思

			前面的部分就不解释了,后面的就是 Channel 的接收不会执行,因为这里如果跟上面的方法一样执行了,那就是给取出来了,
			结果就不会 打印了show1 后还能打印两次接收的c2的值
	*/
	select02()
}

func showStr1() int {
	uCnt++
	fmt.Println("~~~~~~~~~~~~~11111~~~~~~~~~~~~~~", uCnt)
	return uCnt
}

func showStr2() int {
	uCnt++
	fmt.Println("~~~~~~~~~~~222222~~~~~~~~~~~~~~~", uCnt)
	return uCnt
}

func showStr3() int {
	uCnt++
	fmt.Println("~~~~~~~~~~~333333~~~~~~~~~~~~~~~", uCnt)
	return uCnt
}

func select01() {
	c1 := make(chan int)

	go func() {
		for v := range c1 {
			if v != 0 {
				fmt.Println("++++++++", v)
			}
		}
	}()

	for i := 1; i <= 3; i++ {
		select {
		case c1 <- showStr1():
			fmt.Println("show1 ================", i)
		case c1 <- showStr2():
			fmt.Println("show2 ================", i)
		case c1 <- showStr3():
			fmt.Println("show3 ================", i)
		}
	}

	close(c1)

	/*
		某次输出结果

		~~~~~~~~~~~~~11111~~~~~~~~~~~~~~ 1
		~~~~~~~~~~~222222~~~~~~~~~~~~~~~ 2
		~~~~~~~~~~~333333~~~~~~~~~~~~~~~ 3
		show1 ================ 1
		~~~~~~~~~~~~~11111~~~~~~~~~~~~~~ 4
		~~~~~~~~~~~222222~~~~~~~~~~~~~~~ 5
		~~~~~~~~~~~333333~~~~~~~~~~~~~~~ 6
		++++++++ 1
		++++++++ 5
		show2 ================ 2
		~~~~~~~~~~~~~11111~~~~~~~~~~~~~~ 7
		~~~~~~~~~~~222222~~~~~~~~~~~~~~~ 8
		~~~~~~~~~~~333333~~~~~~~~~~~~~~~ 9
		show3 ================ 3
		++++++++ 9
	*/
}

func select02() {
	c1 := make(chan int)
	c2 := make(chan int)

	go func() {
		for v := range c1 {
			if v != 0 {
				fmt.Println("++++++++", v)
			}
		}
	}()

	go func() {
		c2 <- 88
		c2 <- 99
	}()

	for i := 1; i <= 5; i++ {
		select {
		case c1 <- showStr1():
			fmt.Println("show1 ================", i)
		case c1 <- showStr2():
			fmt.Println("show2 ================", i)
		case c1 <- showStr3():
			fmt.Println("show3 ================", i)
		case mV := <-c2:
			fmt.Println("mV := <-c2 ================", i, mV)
		}
	}

	close(c1)

	/*
		某次输出结果

		~~~~~~~~~~~~~11111~~~~~~~~~~~~~~ 1
		~~~~~~~~~~~222222~~~~~~~~~~~~~~~ 2
		~~~~~~~~~~~333333~~~~~~~~~~~~~~~ 3
		show1 ================ 1
		~~~~~~~~~~~~~11111~~~~~~~~~~~~~~ 4
		~~~~~~~~~~~222222~~~~~~~~~~~~~~~ 5
		~~~~~~~~~~~333333~~~~~~~~~~~~~~~ 6
		mV := <-c2 ================ 2 88
		~~~~~~~~~~~~~11111~~~~~~~~~~~~~~ 7
		~~~~~~~~~~~222222~~~~~~~~~~~~~~~ 8
		~~~~~~~~~~~333333~~~~~~~~~~~~~~~ 9
		mV := <-c2 ================ 3 99
		~~~~~~~~~~~~~11111~~~~~~~~~~~~~~ 10
		++++++++ 1
		~~~~~~~~~~~222222~~~~~~~~~~~~~~~ 11
		~~~~~~~~~~~333333~~~~~~~~~~~~~~~ 12
		show1 ================ 4
		~~~~~~~~~~~~~11111~~~~~~~~~~~~~~ 13
		~~~~~~~~~~~222222~~~~~~~~~~~~~~~ 14
		~~~~~~~~~~~333333~~~~~~~~~~~~~~~ 15
		++++++++ 10
		++++++++ 14
		show2 ================ 5
	*/
}

一点点笔记,以便以后翻阅。

相关推荐
知无不研4 小时前
lambda表达式的使用(3)
开发语言·c++·lambda
cfm_29144 小时前
SpringAI + Ollama 本地大模型
java·开发语言·人工智能·语言模型
IT_陈寒5 小时前
Python的GIL让我多写了500行代码
前端·人工智能·后端
C++ 老炮儿的技术栈5 小时前
基于Qt实现轻量化本地音乐播放器
开发语言·c++·qt·c·播放器·音乐
qq_448011165 小时前
C语言中的柔性数组
c语言·开发语言·柔性数组
小白学大数据5 小时前
长周期爬虫的数据一致性:断点续爬 + 事务回滚保障采集质量
开发语言·爬虫·测试工具
zlinear数据采集卡6 小时前
D223上位机C#开发实战:从帧解析到波形显示的完整实现
开发语言·arm开发·嵌入式硬件·fpga开发·开源·c#
Poo_Chai6 小时前
QT emit信号后完整处理流程,包括槽函数响应流程
java·开发语言·数据库
IT爱学堂6 小时前
精讲软件设计师(软考中级)一站式通关课_实战课程_慕课网
后端
瑞码空间6 小时前
Java 图形界面(GUI)完整知识点手册
java·开发语言·图形界面·swing