Go 中的
switch
和 select
有什么区别吗,switch
switch
用于根据任何类型的变量值做出决策。阅读this了解更多详情:
Go 的
比 C 更通用。表达式不必是常量甚至整数,从上到下评估情况,直到找到匹配项,如果switch
没有表达式,则会打开switch
。因此,可以将 if-else-if-else 链写为true
。switch
使用示例:(去游乐场)
package main
import (
"fmt"
"runtime"
)
func main() {
fmt.Print("Go runs on ")
switch os := runtime.GOOS; os {
case "darwin":
fmt.Println("OS X.")
case "linux":
fmt.Println("Linux.")
default:
// freebsd, openbsd,
// plan9, windows...
fmt.Printf("%s.", os)
}
}
select
select
语句让一个goroutine等待多个通信操作。
select 会阻塞,直到它的一个 case 可以运行,然后执行该 case。如果准备好多个,它会随机选择一个。这是一个例子:(Go Playground)
package main
import (
"fmt"
"time"
)
func main() {
tick := time.Tick(100 * time.Millisecond)
boom := time.After(500 * time.Millisecond)
for {
select {
case <-tick:
fmt.Println("tick.")
case <-boom:
fmt.Println("BOOM!")
return
default:
fmt.Println(" .")
time.Sleep(50 * time.Millisecond)
}
}
}
“select”语句选择一组可能的发送或发送中的哪一个 接收操作将继续进行。看起来类似于“开关” 声明,但案例均涉及沟通 操作。
“Switch”语句提供多路执行。表达式或类型 说明符与“switch”内的“cases”进行比较以确定 要执行哪个分支。有两种形式:表达式开关和 类型开关。在表达式开关中,cases 包含表达式 与 switch 表达式的值进行比较。在一个 类型开关,案例包含与 特殊注释的 switch 表达式的类型。开关表达式 在 switch 语句中只计算一次。
是的,有很多差异:
select
仅适用于通道事件(接收、关闭或等待),但您可以使用 switch
仅用于比较通道数据,如 case <-ch == 1:
switch
以确定性方式工作,就像多个 if
或 if else
语句一样,但是 select
以非确定性方式选择 case
:你不能说哪个 case 在 select
fallthrough
中使用
select
switch
将表达式或类型说明符与 cases
内的 switch
进行比较,以确定要执行哪个分支。switch
本身不会阻塞,但 select
会阻塞底层 goroutine,除非你使用 default
switch
有两种形式:表情开关和类型开关select
(没有default
)没有CPU使用率(goroutine睡眠)select
不同,您不能在 case <-ch:
中使用 switch
。工作示例代码:
package main
import "fmt"
func main() {
ch := make(chan int, 4)
ch <- 1
ch <- 2
ch <- 3
ch <- 4
close(ch)
switch {
//case <-ch: // invalid case <-ch in switch (mismatched types int and bool)
case <-ch == 1:
fmt.Println("switch1")
fallthrough
case <-ch == 2:
fmt.Println("switch2")
}
select {
case d := <-ch:
fmt.Println("select1 d=", d)
case d := <-ch:
fmt.Println("select2 d=", d)
}
}
输出:
switch1
switch2
select2 d= 2
另一次运行的输出:
switch1
switch2
select1 d= 2