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

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

相关推荐
我崽不熬夜1 分钟前
Java的条件语句与循环语句:如何高效编写你的程序逻辑?
java·后端·java ee
我崽不熬夜35 分钟前
Java中的String、StringBuilder、StringBuffer:究竟该选哪个?
java·后端·java ee
文火冰糖的硅基工坊40 分钟前
[激光原理与应用-317]:光学设计 - Solidworks - 草图
开发语言·python·信息可视化·系统架构
草莓熊Lotso1 小时前
【C语言强化训练16天】--从基础到进阶的蜕变之旅:Day10
c语言·开发语言·经验分享·算法·强化
bing.shao1 小时前
gRPC 选型 etcd 的核心优势分析
数据库·微服务·云原生·golang·etcd
草明1 小时前
docker stats 增加一列容器名称的显示
java·开发语言·docker
我崽不熬夜1 小时前
Java中的基本数据类型和包装类:你了解它们的区别吗?
java·后端·java ee
每天学习一丢丢1 小时前
SpringBoot + Vue实现批量导入导出功能的标准方案
vue.js·spring boot·后端
He1955011 小时前
Go初级二
开发语言·后端·golang
一只拉古2 小时前
DevOps 基础到精通 - 部署策略
后端·自动化运维·devops