人生就是由多个选择组成的,而真正重要的选择并不多,比如在什么学校读书,和谁谈恋爱,做什么工作,把时间更多的花在什么上面。而在选择的背后,也存在着我们赖以生存的环境,在什么样的环境,开什么样的花。
在go语言有一个select关键字。说到select,给人的印象是在一群可选项里面去选择一部分出来,另一部分会被淘汰或者不会被使用到。而在我们的生活里面也出现了很多这样的选择,比如考大学,一个大的高考群体被筛选到多个学校去,参加体育比赛,有的人会得奖有的人只是陪跑。谈恋爱,根据自己的喜好和三观去选择对象,也可以根据同样的原则选择和谁分手。
相对没有被选择的部分来讲,人们往往更加关心被选择的这部分接下来会有什么样的发展,正如在select的情况下,总会做点什么事情。毕竟人们都比较愿意去接受人生中成功的部分。
说到channel,上次我们已经知道对他的主要操作就是读和写,就像一个信箱,然而一个信箱也不总是能够读写的,作为一个工具,我们根据自己的升高经验来说,也会遇到工具不能用的时候,而channel也是如此,select面对一个channel或者多个channel来做选择的时候,也和人一样,要去选择现在可以用的channel。
现在来看看最简单的一种情况,就是select一个channel的情况。
package main
import "fmt"
func main() {
//创建一个chan
ch := make(chan int, 1)
//给ch加入一个值
ch <- 1
select {
case data := <-ch:
fmt.Println("you=", data)
case data2 := <-ch:
fmt.Println("me=", data2)
}
fmt.Println("main end")
}
我们多次执行这个程序的时候,发现结果里面可能包含you也可能包含me,也就是面对一个channel的时候,在多个case的情况下,选择是随机的。
当我们不给channel输入值的时候,程序就会阻塞,所以一般我们会在case之后给一个默认行为。
package main
import "fmt"
func main() {
//创建一个chan
ch := make(chan int, 1)
//给ch加入一个值
//ch <- 1
select {
case data := <-ch:
fmt.Println("you=", data)
case data2 := <-ch:
fmt.Println("me=", data2)
default:
fmt.Println("default--")
}
fmt.Println("main end")
}
另外我们可以用select来做超时的提示,如下
package main
import (
"fmt"
"time"
)
func main() {
info := make(chan bool, 1)
select {
//可以获取到info
case <-info:
fmt.Println("ok")
//2秒后就超时提示 time.After返回了一个channel
case <-time.After(time.Second * 2):
fmt.Println("timeout")
}
fmt.Println("main end")
}
提示:当我们在同一个包下面写多个文件,每个文件都是main包,同时有main方法的时候,执行main方法会弹出一个选择框
Run kind下拉框,选择File 而不是Package。
这里超时的原理就是,第一个channel如果没有准备好,在2秒后就会有另一个channel准备好,然后基于这个准备好的channel做超时的提示。
总结 select 选择的是一个准备好的可用的channel,当有多个channel都准备好了,会随机选择一个,使用select case的阻塞特点,可以给程序的操作做超时的提示。
最后送上红楼梦一句诗:五才可去补苍天,枉入红尘若许年。