select

一.简介

select是Go语言特有的操作,使用select我们可以同时在多个channel上进行发送/接收操作.select的用法与switch语言非常类似,由select开始一个新的选择块,每个选择条件由
case语句来描述。与switch语句可以选择任何可使用相等比较的条件相比,select有比较多的限制,其中最大的一条限制就是每个case语句里必须是一个IO操作,大致的结构如下:

select {
	case <-chan1:
	// 如果chan1成功读到数据,则进行该case处理语句
	case chan2 <- 1:
	// 如果成功向chan2写入数据,则进行该case处理语句
	default:
	// 如果上面都没有成功,则进入default处理流程
}

  

可以看出,select不像switch,后面并不带判断条件,而是直接去查看case语句。

二.基本示例

示例:

func main() {
	ch := make(chan int, 1) // 创建1个缓存区大小的channel
	for {
		select {
			case ch <- 1:
			case ch <- 0:
		}
		i := <-ch
		fmt.Println("Value received:", i)
	}
}

  

这将随机输出0和1
make(chan int, 1),这表示创建1个缓存区大小的channel,如果没有该参数,因为channel的特性,将造成一个死锁.

default:

func main() {
	ch1 := make(chan int)
	ch2 := make(chan int)

	select {
	case <-ch1:
		fmt.Println(<-ch1)
	case <-ch2:
		fmt.Println(<-ch2)
	default:
		fmt.Println("default")
	}
}

  

ch1和ch2都为空,所以default执行

三.超时机制或缓存数目检查

1.超时机制

func main() {
	timeout := make(chan bool, 1) // 带缓存超时channel
	ch := make(chan int)

	go func() {
		time.Sleep(1 * time.Second) // 超时时间
		timeout <- true
	}()

	select {
	case <-ch:
		fmt.Println(ch)
	case <-timeout:
		fmt.Println("time out range")

	}
}

  

2.检查缓存是否已满

func main() {
	ch := make(chan int, 1)
	ch <- 1

	select {
	case ch <- 2:
		fmt.Println(ch)
	default:
		fmt.Println("cache num is enough")

	}
}

  

原文地址:https://www.cnblogs.com/itfenqing/p/7634217.html