go语言学习笔记——select的使用

160 阅读1分钟

select的使用场景

多路选择关键字是select,功能类似switch,主要是结合channel进行使用

主要用法

select {
	case <-ch1:
		fmt.Println("1234")
	default:
		fmt.Println("There is nothing")
	}

在使用select的时候,有以下注意的事项:

  • 每个case必须是channel
  • 只要是命中一个case,就会执行对应的逻辑,其他的case都不会执行
  • 如果所有的case都准备好了,会随机选择一个进行执行,其他的不会执行
  • 如果所有的case都没有准备好,如果有default,就会执行default,否则,会阻塞

举个例子

func TestSelect(t *testing.T) {
	var ch1, ch2 chan int
	ch1 = CreateCh()
	ch2 = CreateCh()
	select {
	case <-ch1:
		t.Log("ch1 returns")
	case <-ch2:
		t.Log("ch2 returns")
	}
}

func CreateCh() chan int {
	ch1 := make(chan int)
	go func() {
		for i := 0; i < 10; i++ {
			ch1 <- i
		}
	}()
	return ch1
}

在运行TestSelect的方法的时候,多次运行,会发现随机输出ch2 returns或ch1 returns

但是每次也只会执行某一个case,并不会执行其他的case

稍加做下改造

func TestSelect(t *testing.T) {
	var ch1, ch2 chan int
	ch1 = CreateCh()
	ch2 = CreateCh()
	select {
	case <-ch1:
		t.Log("ch1 returns")
	case <-ch2:
		t.Log("ch2 returns")
	default:
		t.Log("nothings returns")
	}
}

func CreateCh() chan int {
	ch1 := make(chan int)
	go func() {
		for i := 0; i < 10; i++ {
			time.Sleep(time.Second * 2)
			ch1 <- i
		}
	}()

	return ch1
}

这个和上面不同的是,增加了default,在想channel里面写数据的时候进行了sleep,这个时候再次运行TestCase的时候,由于ch1和ch2都没有准备好,则每次都会运行default