What is the difference between a switch and a choice in Go?

Is there a difference between switch and select in Go,
except that one accepts the argument and the other does not?

+7
switch-statement go goroutine
source share
3 answers

A select used only with channels. Example

A switch used with specific types. Example

A select will select several valid parameters randomly, and the switch will go in sequence (and it would take a pass to match several.)

Note that the switch can also switch to interface types when used with a keyword .(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." 
+12
source share

switch is used to make decisions based on the value of a variable of any type. Read more:

The Go switch is more general than C. The expressions do not have to be constants or even integers, cases are evaluated from top to bottom until a match is found, and if the switch has no expression, it turns on true. Therefore, it is possible - and idiomatically - to write an if-else-if-else chain as a switch.

Example usage: ( 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) } } 

The select statement allows goroutine to wait for several communication operations.

Selects blocks until one of his cases can be started, then he executes this case. He chooses one randomly, if several are ready. Here is one example: ( 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) } } } 
+11
source share

Select statements

The select statement selects which of the many possible receive operations will continue. It looks like a β€œswitch”, but with all cases related to communicating operations.

Switch statements

Operators

"Switch" provides multi-threaded execution. An expression or type specifier is compared with the "cases" inside the "switch" to determine which branch to execute. There are two forms: expression and type switches. In an expression selector, cases contain expressions that are compared to the value of the switch expression. In a type, cases contain types that are compared to the type of a particular expression. The switch expression is evaluated exactly once in the switch statement.

Yes, there are many differences:

  • select only works on channel events (receive, close or wait), but you can use switch only to compare channel data, for example case <-ch == 1:
  • switch works in a deterministic way, like several if or if else , but select selects case non-deterministic way: you cannot tell which case is executed first in select
  • you cannot use fallthrough in select
  • in switch The specifier of an expression or type is compared with cases inside the switch to determine which branch to execute.
  • switch does not block itself, but select blocks the base goroutine unless you use default
  • switch has two forms: expression switches and type switches.
  • when locking select (without default ) there is no CPU usage (goroutine sleep)
  • Unlike select you cannot use case <-ch: inside switch .

Working code example:

 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) } } 

exit:

 switch1 switch2 select2 d= 2 

output of another run:

 switch1 switch2 select1 d= 2 
0
source share

All Articles