Golang中switch语句和select语句的用法教程
本文主要给大家介绍了关于Golang中switch和select用法的相关内容,分享出来供大家参考学习,下面来一起看看详细的介绍:
一、switch语句
switch语句提供了一个多分支条件执行的方法。每一个case可以携带一个表达式或一个类型说明符。前者又可被简称为case表达式。因此,Go语言的switch语句又分为表达式switch语句和类型switch语句。
1、表达式switch语句
varnamestring ... switchname{ case"Golang": fmt.Println("Golang") case"Rust": fmt.Println("Rust") default: fmt.Println("PHP是世界上最好的语言") }
Go会依照从上至下的顺序对每一条case语句中case表达式进行求值,只要被发现其表达式与switch表达式的结果相同,该case语句就会被选中。其余的case语句会被忽略。 与if相同,switch语句还可以包含初始化字句,且其出现位置和写法如出一辙:
names:=[]string{"Golang","java","PHP"} switchname:=names[0];name{ case"Golang": fmt.Println("Golang") ... default: fmt.Println("Unknown") }
2、类型switch语句
类型switch语句与一般形式有两点差别。第一点,紧随case关键字的不是表达式,而是类型说明符。类型说明符由若干个类型字面量组成,且多个类型字面量之间由英文逗号分隔。第二点,它的switch表达式是非常特殊的。这种特殊的表达式也起到了类型断言的作用,但其表现形式很特殊,如:v.(type),其中v必须代表一个接口类型的值。该类表达式只能出现在类型switch语句中,且只能充当switch表达式。一个类型switch语句的示例如下:
v:=11 switchi:=interface{}(v).(type){ caseint,int8,int16,int32,int64: fmt.Println("Asignedinteger:%d.Thetypeis%T.\n",v,i) caseuint,uint8,uint16,uint32,uint64: fmt.Println("Aunsignedinteger:%d.Thetypeis%T.\n",v,i) default: fmt.Println("Unknown!") }
我们这里把switch表达式的结果赋给了一个变量。如此以来,我们就可以在该switch语句中使用这个结果了。这段代码被执行后,输出:"Asignedinteger:11.Thetypeisint."
最后说一下fallthrough。它既是一个关键字,又可以代表一条语句。fallthrough语句可被包含在表达式switch语句中的case语句中。它的作用是使控制权流转到下一个case。不过要注意fallthrough语句仅能作为case语句中的最后一条语句出现。并且,包含它的case语句不是其所属switch语句的最后一条case语句。
二、select语句
golang的select的功能和select,poll,epoll相似,就是监听IO操作,当IO操作发生时,触发相应的动作。
示例:
ch1:=make(chanint,1) ch2:=make(chanint,1) ... select{ case<-ch1: fmt.Println("ch1poponeelement") case<-ch2: fmt.Println("ch2poponeelement") }
注意到select的代码形式和switch非常相似,不过select的case里的操作语句只能是【IO操作】。
此示例里面select会一直等待等到某个case语句完成,也就是等到成功从ch1或者ch2中读到数据。则select语句结束。
break语句也可以被包含在select语句中的case语句中。它的作用是立即结束当前的select语句的执行。不论其所属的case语句中是否还有未被执行的语句。
【使用select实现timeout机制】
如下:
timeout:=make(chanbool,1) gofunc(){ time.Sleep(time.Second*10) timeout<-true }() select{ case<-pssScanResponseChan: case<-timeout: fmt.PrintIn("timeout!") }
当超时时间到的时候,case2会操作成功。所以select语句则会退出。而不是一直阻塞在ch的读取操作上。从而实现了对ch读取操作的超时设置。
下面这个更有意思一点。
当select语句带有default的时候:
ch1:=make(chanint,1) ch2:=make(chanint,1) select{ case<-ch1: fmt.Println("ch1poponeelement") case<-ch2: fmt.Println("ch2poponeelement") default: fmt.Println("default") }
此时因为ch1和ch2都为空,所以case1和case2都不会读取成功。则select执行default语句。
就是因为这个default特性,我们可以使用select语句来检测chan是否已经满了。
如下:
ch:=make(chanint,1) ch<-1 select{ casech<-2: default: fmt.Println("channelisfull!") }
因为ch插入1的时候已经满了,当ch要插入2的时候,发现ch已经满了(case1阻塞住),则select执行default语句。这样就可以实现对channel是否已满的检测,而不是一直等待。
比如我们有一个服务,当请求进来的时候我们会生成一个job扔进channel,由其他协程从channel中获取job去执行。但是我们希望当channel瞒了的时候,将该job抛弃并回复【服务繁忙,请稍微再试。】就可以用select实现该需求。
此外,利用default特性,我们可以使用select语句将chan清空,如下:
flag:=false for{ select{ case<-pssScanResponseChan: continue default: flag=true } iftrue==flag{ break } }
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对毛票票的支持。