关于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
	*/
}

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

相关推荐
Victor35616 小时前
https://editor.csdn.net/md/?articleId=139321571&spm=1011.2415.3001.9698
后端
Victor35616 小时前
Hibernate(89)如何在压力测试中使用Hibernate?
后端
灰子学技术18 小时前
go response.Body.close()导致连接异常处理
开发语言·后端·golang
二十雨辰19 小时前
[python]-AI大模型
开发语言·人工智能·python
Yvonne爱编码19 小时前
JAVA数据结构 DAY6-栈和队列
java·开发语言·数据结构·python
Re.不晚19 小时前
JAVA进阶之路——无奖问答挑战1
java·开发语言
你这个代码我看不懂19 小时前
@ConditionalOnProperty不直接使用松绑定规则
java·开发语言
pas13619 小时前
41-parse的实现原理&有限状态机
开发语言·前端·javascript
Gogo81619 小时前
BigInt 与 Number 的爱恨情仇,为何大佬都劝你“能用 Number 就别用 BigInt”?
后端
fuquxiaoguang19 小时前
深入浅出:使用MDC构建SpringBoot全链路请求追踪系统
java·spring boot·后端·调用链分析