Golang中switch语句和select语句的用法教程

作者:逝水-无痕 时间:2023-09-02 09:09:06 

本文主要给大家介绍了关于Golang中switch和select用法的相关内容,分享出来供大家参考学习,下面来一起看看详细的介绍:

一、switch语句

switch语句提供了一个多分支条件执行的方法。每一个case可以携带一个表达式或一个类型说明符。前者又可被简称为case表达式。因此,Go语言的switch语句又分为表达式switch语句和类型switch语句。

1、表达式switch语句


var name string
...
switch name {
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"}
switch name:=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
switch i := interface{}(v).(type) {
case int, int8, int16, int32, int64:
fmt.Println("A signed integer:%d. The type is %T. \n", v, i)
case uint, uint8, uint16, uint32, uint64:
fmt.Println("A unsigned integer: %d. The type is %T. \n", v, i)
default:
fmt.Println("Unknown!")
}

我们这里把switch表达式的结果赋给了一个变量。如此以来,我们就可以在该switch语句中使用这个结果了。这段代码被执行后,输出:"A signed integer:11. The type is int. "

最后说一下fallthrough。它既是一个关键字,又可以代表一条语句。fallthrough语句可被包含在表达式switch语句中的case语句中。它的作用是使控制权流转到下一个case。不过要注意fallthrough语句仅能作为case语句中的最后一条语句出现。并且,包含它的case语句不是其所属switch语句的最后一条case语句。

二、select语句

golang 的 select 的功能和 select, poll, epoll 相似, 就是监听 IO 操作,当 IO 操作发生时,触发相应的动作。

示例:


ch1 := make (chan int, 1)
ch2 := make (chan int, 1)

...

select {
case <-ch1:
fmt.Println("ch1 pop one element")
case <-ch2:
fmt.Println("ch2 pop one element")
}

注意到 select 的代码形式和 switch 非常相似, 不过 select 的 case 里的操作语句只能是【IO 操作】 。

此示例里面 select 会一直等待等到某个 case 语句完成, 也就是等到成功从 ch1 或者 ch2 中读到数据。 则 select 语句结束。

break语句也可以被包含在select语句中的case语句中。它的作用是立即结束当前的select语句的执行。不论其所属的case语句中是否还有未被执行的语句。

【使用 select 实现 timeout 机制】

如下:


timeout := make(chan bool, 1)
go func() {
time.Sleep(time.Second * 10)
timeout <- true
}()
select {
case <-pssScanResponseChan:

case <-timeout:
fmt.PrintIn("timeout!")
}

当超时时间到的时候,case2 会操作成功。 所以 select 语句则会退出。 而不是一直阻塞在 ch 的读取操作上。 从而实现了对 ch 读取操作的超时设置。

下面这个更有意思一点。

当 select 语句带有 default 的时候:


ch1 := make (chan int, 1)
ch2 := make (chan int, 1)

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

此时因为 ch1 和 ch2 都为空,所以 case1 和 case2 都不会读取成功。 则 select 执行 default 语句。

就是因为这个 default 特性, 我们可以使用 select 语句来检测 chan 是否已经满了。

如下:


ch := make (chan int, 1)
ch <- 1
select {
case ch <- 2:
default:
fmt.Println("channel is full !")
}

因为 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
}
if true == flag {
break
}
}

来源:http://blog.csdn.net/wangkai_123456/article/details/72640014

标签:golang,switch,select
0
投稿

猜你喜欢

  • python发送邮件接收邮件示例分享

    2023-05-25 02:01:47
  • 可以用ASP生成由客户浏览器处理的客户端脚本吗?

    2009-11-01 18:06:00
  • 30个运用纸类元素网页设计的创意实例欣赏

    2009-04-20 12:49:00
  • python 字典(dict)按键和值排序

    2021-11-20 05:44:35
  • vue基于websocket实现智能聊天及吸附动画效果

    2024-04-30 08:45:20
  • python设计模式之抽象工厂模式详解

    2023-06-11 22:15:51
  • 系统默认的MySQL用户名消失的解决方法

    2008-12-02 14:26:00
  • C#简单访问SQLite数据库的方法(安装,连接,查询等)

    2024-01-22 18:29:22
  • python使用插值法画出平滑曲线

    2021-07-14 03:59:02
  • Python中__init__.py文件的作用详解

    2021-12-22 13:04:05
  • 理解Sql Server中的聚集索引

    2024-01-23 11:51:46
  • SQL Server服务器内存升级后的烦恼

    2008-12-22 10:55:00
  • python字符串循环左移

    2023-08-28 19:32:13
  • js阻止移动端页面滚动的两种方法

    2023-08-04 17:36:12
  • JavaScript中Infinity(无穷数)的使用和注意事项

    2023-08-21 00:59:13
  • 如何通过Python3和ssl实现加密通信功能

    2022-04-28 05:55:30
  • python条件和循环的使用方法

    2021-12-16 22:27:59
  • Django实现简单登录的示例代码

    2022-03-26 04:10:18
  • Python 爬虫之Beautiful Soup模块使用指南

    2021-10-16 13:28:03
  • python数字图像处理像素的访问与裁剪示例

    2023-05-12 11:07:20
  • asp之家 网络编程 m.aspxhome.com