关于go中的select

笔记仓库:gitee.com/xiaoyinhui


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

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


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

  • 10
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小印丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值