除了一个函数需要参数,另一个不需要,Go语言中的
switch
和select
有什么区别吗?switch
和select
有什么区别吗?switch 语句基于变量值(任意类型)做出决策。阅读 此文档 以获取更多细节:
Go 的 switch 功能比 C 更为通用。表达式不必是常量或整数,case 会从上到下逐一进行评估直到找到匹配项,如果 switch 没有表达式则默认为 true。因此,使用 switch 可以编写 if-else-if-else 链,这是惯用方法。
示例用法:(Go Playground)
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语句允许一个goroutine等待多个通信操作。
当其中一个case可以运行时,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”语句提供多路执行。表达式或类型说明符与“switch”内部的“case”进行比较,以确定要执行的分支。有两种形式:表达式开关和类型开关。在表达式开关中,情况包含与开关表达式的值进行比较的表达式。在类型开关中,情况包含与特殊注释的开关表达式的类型进行比较的类型。在switch语句中,switch表达式仅计算一次。
是的,有很多不同之处:
select
只适用于通道事件(接收、关闭或等待),但您可以使用switch
仅用于比较通道数据,例如case <-ch == 1:
switch
以确定性方式工作,就像多个if
或if else
语句一样,但是select
以非确定性方式选择case
:您无法说哪个情况在select
中首先运行select
中使用fallthrough
switch
中,将表达式或类型说明符与switch
内部的cases
进行比较,以确定要执行的分支。switch
本身不会阻塞,但是select
会阻塞底层goroutine,除非您使用default
switch
有两种形式:表达式开关和类型开关select
(没有default
)中,没有CPU使用率(goroutine睡眠)select
不同,您不能在switch
中使用case <-ch:
工作示例代码:
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