Go 中的 switch 和 select 有什么区别?
What is the difference between switch and select in Go?
围棋switch
和select
有区别吗,
除了一个争论另一个不争论的事实?
switch用于根据任意类型的变量值进行判断。阅读 this 了解更多详情:
Go's switch is more general than C's. The expressions need not be constants or even integers, the cases are evaluated top to bottom until a match is found, and if the switch has no expression it switches on true. It's therefore possible—and idiomatic—to write an if-else-if-else chain as a switch.
示例使用:(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 等待多个通信操作。
A 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)
}
}
}
A select
仅用于频道。 Example
A switch
与具体类型一起使用。 Example
A select
将随机选择多个有效选项,而 switch
将按顺序进行(并且需要 fallthrough 才能匹配多个。)
请注意,当与关键字 .(type)
一起使用时,开关也可以遍历接口类型
var a interface{}
a = 5
switch a.(type) {
case int:
fmt.Println("an int.")
case int32:
fmt.Println("an int32.")
}
// in this case it will print "an int."
A "select" statement chooses which of a set of possible send or
receive operations will proceed. It looks similar to a "switch"
statement but with the cases all referring to communication
operations.
"Switch" statements provide multi-way execution. An expression or type
specifier is compared to the "cases" inside the "switch" to determine
which branch to execute. There are two forms: expression switches and
type switches. In an expression switch, the cases contain expressions
that are compared against the value of the switch expression. In a
type switch, the cases contain types that are compared against the
type of a specially annotated switch expression. The switch expression
is evaluated exactly once in a switch statement.
是的,有很多区别:
select
仅适用于通道事件(接收、关闭或等待),但您可以使用 switch
仅用于比较通道数据,例如 case <-ch == 1:
switch
像多个 if
或 if else
语句一样以确定性方式工作,但 select
以非确定性方式选择 case
:你可以不要说 select
中第一个 运行 的情况
- 您不能在
select
中使用 fallthrough
- in
switch
将表达式或类型说明符与 switch
中的 cases
进行比较,以确定要执行的分支。
switch
不会阻塞自身,但是 select
会阻塞底层 goroutine,除非你使用 default
switch
有两种形式:表达式开关和类型开关
- 阻塞
select
(没有default
)没有CPU使用(goroutine sleep)
- 与
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
围棋switch
和select
有区别吗,
除了一个争论另一个不争论的事实?
switch用于根据任意类型的变量值进行判断。阅读 this 了解更多详情:
Go's switch is more general than C's. The expressions need not be constants or even integers, the cases are evaluated top to bottom until a match is found, and if the switch has no expression it switches on true. It's therefore possible—and idiomatic—to write an if-else-if-else chain as a switch.
示例使用:(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 等待多个通信操作。
A 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)
}
}
}
A select
仅用于频道。 Example
A switch
与具体类型一起使用。 Example
A select
将随机选择多个有效选项,而 switch
将按顺序进行(并且需要 fallthrough 才能匹配多个。)
请注意,当与关键字 .(type)
var a interface{}
a = 5
switch a.(type) {
case int:
fmt.Println("an int.")
case int32:
fmt.Println("an int32.")
}
// in this case it will print "an int."
A "select" statement chooses which of a set of possible send or receive operations will proceed. It looks similar to a "switch" statement but with the cases all referring to communication operations.
"Switch" statements provide multi-way execution. An expression or type specifier is compared to the "cases" inside the "switch" to determine which branch to execute. There are two forms: expression switches and type switches. In an expression switch, the cases contain expressions that are compared against the value of the switch expression. In a type switch, the cases contain types that are compared against the type of a specially annotated switch expression. The switch expression is evaluated exactly once in a switch statement.
是的,有很多区别:
select
仅适用于通道事件(接收、关闭或等待),但您可以使用switch
仅用于比较通道数据,例如case <-ch == 1:
switch
像多个if
或if else
语句一样以确定性方式工作,但select
以非确定性方式选择case
:你可以不要说select
中第一个 运行 的情况
- 您不能在
select
中使用 - in
switch
将表达式或类型说明符与switch
中的cases
进行比较,以确定要执行的分支。 switch
不会阻塞自身,但是select
会阻塞底层 goroutine,除非你使用default
switch
有两种形式:表达式开关和类型开关- 阻塞
select
(没有default
)没有CPU使用(goroutine sleep) - 与
select
不同,您不能在switch
中使用case <-ch:
。
fallthrough
工作示例代码:
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