Golang 用法 select 语句

Golang 用法 select 语句

跟 switch-case 相比,select-case 用法比较单一,它仅能用于 信道/通道 的相关操作

select {
    case 表达式1:
        <code>
    case 表达式2:
        <code>
    default:
        <code>
}

一个简单的例子

func TestSelect01(t *testing.T) {
	c1 := make(chan string, 1)
	c2 := make(chan string, 1)

	c2 <- "hello"

	select {
	case msg1 := <-c1:
		fmt.Println("main goroutine , c1 received: ", msg1)
	case msg2 := <-c2:
		fmt.Println("main goroutine , c2 received: ", msg2)
	default:
		fmt.Println("main goroutine , No data received.")
	}
}

输出

main goroutine , c2 received:  hello

在运行 select 时,会遍历所有(如果有机会的话)的 case 表达式,只要有一个信道有接收到数据,那么 select 就结束,所以输出c2。

避免造成死锁

  1. select 在执行过程中,必须命中其中的某一分支。
  2. 如果在遍历完所有的 case 后,若没有命中,任何一个 case 表达式,就会进入 default 里的代码分支。
  3. 但如果你没有写 default 分支,select 就会阻塞,直到有某个 case 可以命中,而如果一直没有命中,select 就会抛出 deadlock 的错误,

就像下面这样子

func TestSelect01(t *testing.T) {
	c1 := make(chan string, 1)
	c2 := make(chan string, 1)

	select {
	case msg1 := <-c1:
		fmt.Println("main goroutine , c1 received: ", msg1)
	case msg2 := <-c2:
		fmt.Println("main goroutine , c2 received: ", msg2)
	}
}

输出如下

fatal error: all goroutines are asleep - deadlock!

goroutine 1 [select]:
main.main()
	d:/demo/select_demo.go:11 +0xbb
exit status 2

解决这个问题的方法有两种,一个是,养成好习惯,在 select 的时候,也写好 default 分支代码,尽管你 default 下没有写任何代码。

func TestSelect01(t *testing.T) {
	c1 := make(chan string, 1)
	c2 := make(chan string, 1)

	// c2 <- "hello"

	select {
	case msg1 := <-c1:
		fmt.Println("main goroutine , c1 received: ", msg1)
	case msg2 := <-c2:
		fmt.Println("main goroutine , c2 received: ", msg2)
	default:
		fmt.Println("main goroutine , No data received.")
	}
}

输出

main goroutine , No data received.

另一个是,让其中某一个信道可以接收到数据

func TestSelect01(t *testing.T) {
	c1 := make(chan string, 1)
	c2 := make(chan string, 1)

	go func() {
		time.Sleep(3 * time.Second)
		c2 <- "hello"
	}()

	select {
	case msg1 := <-c1:
		fmt.Println("main goroutine , c1 received: ", msg1)
	case msg2 := <-c2:
		fmt.Println("main goroutine , c2 received: ", msg2)
	}
}

输出

main goroutine , c2 received:  hello
  • 9
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值