Go 中的 switch 和 select 有什么区别?

问题描述 投票:0回答:3

Go 中的

switch
select
有什么区别吗,
除了一个接受争论而另一个不接受这一事实之外?

go switch-statement goroutine
3个回答
102
投票

A

select
仅与通道一起使用。 示例

A

switch
用于具体类型。 示例

A

select
将随机选择多个有效选项,而 a
switch
将按顺序进行(并且需要失败才能匹配多个选项。)

请注意,当与关键字

.(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."

46
投票

switch

switch
用于根据任何类型的变量值做出决策。阅读this了解更多详情:

Go 的

switch
比 C 更通用。表达式不必是常量甚至整数,从上到下评估情况,直到找到匹配项,如果
switch
没有表达式,则会打开
true
。因此,可以将 if-else-if-else 链写为
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)
        }
    }
}

10
投票

选择语句

“select”语句选择一组可能的发送或发送中的哪一个 接收操作将继续进行。看起来类似于“开关” 声明,但案例均涉及沟通 操作。

切换语句

“Switch”语句提供多路执行。表达式或类型 说明符与“switch”内的“cases”进行比较以确定 要执行哪个分支。有两种形式:表达式开关和 类型开关。在表达式开关中,cases 包含表达式 与 switch 表达式的值进行比较。在一个 类型开关,案例包含与 特殊注释的 switch 表达式的类型。开关表达式 在 switch 语句中只计算一次。

是的,有很多差异:

  • select
    仅适用于通道事件(接收、关闭或等待),但您可以使用
    switch
    仅用于比较通道数据,如
    case <-ch == 1:
  • switch
    以确定性方式工作,就像多个
    if
    if else
    语句一样,但是
    select
    以非确定性方式选择
    case
    :你不能说哪个 case 在
    select
  • 中首先运行
  • 您不能在
    fallthrough
     中使用 
    select
  • in
    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
© www.soinside.com 2019 - 2024. All rights reserved.