golang中select和switch的区别

本文介绍了Go语言中select和switch的区别与应用场景。select专用于channel的读写操作,而switch则适用于各种类型的条件判断,包括对接口类型的检查。文章通过示例代码展示了这两种结构的不同之处。

select 和 switch 是 Go语言中进行分支操作的两个方式,各有各的应用场景。

select

select只能应用于channel的操作,既可以用于channel的数据接收,也可以用于channel的数据发送。

如果select的多个分支都满足条件,则会随机的选取其中一个满足条件的分支, 如语言规范中所说:

If multiple cases can proceed, a uniform pseudo-random choice is made to decide which single communication will execute.

`case`语句的表达式可以为一个变量或者两个变量赋值。

default语句。

下面的代码是 go by example 上的例子:

     
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
     
package main  
import "time"
import "fmt"
func main() {
c1 := make( chan string)
c2 := make( chan string)
go func() {
time.Sleep(time.Second * 1)
c1 <- "one"
}()
go func() {
time.Sleep(time.Second * 2)
c2 <- "two"
}()
for i := 0; i < 2; i++ {
select {
case msg1 := <-c1:
fmt.Println( "received", msg1)
case msg2 := <-c2:
fmt.Println( "received", msg2)
}
}
}

switch

switch可以为各种类型进行分支操作, 设置可以为接口类型进行分支判断(通过i.(type))。

switch 分支是顺序执行的,这和select不同。

     
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
     
package main
import "fmt"
import "time"
func main() {
i := 2
fmt.Print( "Write ", i, " as ")
switch i {
case 1:
fmt.Println( "one")
case 2:
fmt.Println( "two")
case 3:
fmt.Println( "three")
}
switch time.Now().Weekday() {
case time.Saturday, time.Sunday:
fmt.Println( "It's the weekend")
default:
fmt.Println( "It's a weekday")
}
t := time.Now()
switch {
case t.Hour() < 12:
fmt.Println( "It's before noon")
default:
fmt.Println( "It's after noon")
}
whatAmI := func(i interface{}) {
switch t := i.( type) {
case bool:
fmt.Println( "I'm a bool")
case int:
fmt.Println( "I'm an int")
default:
fmt.Printf( "Don't know type %T\n", t)
}
}
whatAmI( true)
whatAmI (1)
whatAmI( "hey")
}

原文地址:http://colobu.com/2017/07/07/select-vs-switch-in-golang/

### Golangselect语句的作用适用情况 在Go语言中,`select`语句是一种控制结构,允许一个Goroutine同时等待多个通道操作。它类似于`switch-case`语句,但专门用于处理通道的通信操作。`select`会阻塞,直到其中一个`case`可以继续执行,并且该`case`中的语句会被执行。 #### 用途 - **IO多路复用**:`select`语句是基于Golang运行时的调度器实现的IO多路复用,可以同时监控多个通道的状态[^1]。 - **并发任务处理**:当需要处理多个通道的通信时,`select`语句是非常有用的工具,特别是在需要从多个通道接收数据或向多个通道发送数据的情况下[^2]。 #### 使用场景 - **超时处理**:通过结合`time.After()`函数,可以在指定时间内没有通道操作成功时执行特定的操作。例如,在一秒内没有任何通道操作成功,则执行相应的`case`子句[^2]。 - **非阻塞通道操作**:通过使用`default`子句,可以在没有任何通道操作成功时立即执行某些代码,从而避免程序阻塞[^4]。 - **死锁预防**:需要注意的是,在进入`select`语句时,如果无法获取所有涉及的通道操作数的结果,可能会导致死锁。因此,在设计程序时应确保通道操作能够及时完成以避免这种情况[^3]。 #### 示例代码 以下是一个简单的示例,展示了如何使用`select`语句来处理两个不同的通道: ```go func TestSelect01(t *testing.T) { c1 := make(chan string, 1) c2 := make(chan string, 1) // 向c2通道发送一个值 c2 <- "hello" select { case msg1 := <-c1: fmt.Println("main goroutine , c1 received: ", msg1) case msg2 := <-c2: fmt.Println("main goroutine , c2 received: ", msg2) default: fmt.Println("main goroutine , No data received.") } } ``` 在这个例子中,由于`c2`已经被填充了一个值,所以`select`语句会立即执行`c2`相关的`case`子句,并打印出接收到的消息。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值