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

时间:2016-08-08 04:50:42

标签: go switch-statement goroutine

Go中的switchselect之间是否存在差异,
除了一个人争论而另一个不参与的事实?

3 个答案:

答案 0 :(得分:26)

select仅用于频道。 Example

switch与具体类型一起使用。 Example

select将随机选择多个有效选项,而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."

答案 1 :(得分:20)

开关用于根据任何类型的变量值做出决定。请阅读this了解详情:

  

Go的开关比C更普遍。表达式不必是常量甚至是整数,在找到匹配项之前从上到下评估案例,如果开关没有表达式,则将其置为true。因此,将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等待多个通信操作。

选择块直到其中一个案例可以运行,然后执行该案例。如果多个准备就绪,它会随机选择一个。这是一个例子:(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)
        }
    }
}

答案 2 :(得分:1)

Select statements

  

A&#34;选择&#34;声明选择一组可能的发送或   接收操作将继续。它看起来类似于&#34;开关&#34;   声明,但案件都涉及通信   操作

Switch statements

  

&#34;开关&#34;语句提供多路执行。表达式或类型   说明符与&#34; case&#34;在&#34;开关内#34;确定   要执行哪个分支。有两种形式:表达式开关和   型开关。在表达式开关中,案例包含表达式   与switch表达式的值进行比较。在一个   类型开关,案例包含与之比较的类型   特殊注释的开关表达式的类型。切换表达式   在switch语句中只被评估一次。

是的,有很多不同之处:

  • select仅适用于频道事件(接收,关闭或等待),但您可以仅使用switch来比较频道数据,例如case <-ch == 1:
  • switch以确定性方式工作,例如多个ifif else语句,但select以非确定性方式选择case:您可以&#39 ; t说明哪个案例首先在select
  • 中运行
  • 您无法在fallthrough
  • 中使用select
  • in switch将表达式或类型说明符与cases内的switch进行比较,以确定要执行的分支。
  • switch并未阻止,但select阻止了基础goroutine,除非您使用default
  • switch有两种形式:表达式开关和类型开关
  • 阻塞select(没有default)没有CPU使用率(goroutine sleep)
  • 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