77

Is there any difference between switch and select in Go,
apart from the fact that one takes an argument and the other not?

3 Answers 3

106
+500

A select is only used with channels. Example

A switch is used with concrete types. Example

A select will choose multiple valid options at random, while aswitch will go in sequence (and would require a fallthrough to match multiple.)

Note that a switch can also go over types for interfaces when used with the 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." 
Sign up to request clarification or add additional context in comments.

1 Comment

Would be good if you expanded on the switch explanation. It's not simply restricted to concrete types. By default, it does an equality check, and with no argument, each case statement must be a boolean expression, with the first true case being chosen.
50

switch

switch is used to make a decision based on a variable value of any type. Read this for more details:

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.

Sample Use: (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

The select statement lets a goroutine wait on multiple communication operations.

A select blocks until one of its cases can run, then it executes that case. It chooses one at random if multiple 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) } } } 

1 Comment

This code is a funny joke ⏰💣
11

Select statements

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

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

Yes, there are many differences:

  • select works just on channel events (receive, close or wait), but you can use switch just for comparing channel data like case <-ch == 1:
  • switch works in deterministic way like multiple if or if else statement, but select chooses the case in non-deterministic way: you can't say which case runs first in select
  • you can't use fallthrough in select
  • in switch An expression or type specifier is compared to the cases inside the switch to determine which branch to execute.
  • switch is not blocking itself, but select is blocking underlying goroutine unless you use default
  • switch has two forms: expression switches and type switches
  • in blocking select (without default) there is no CPU usage (goroutine sleep)
  • Unlike select you can't use case <-ch: inside switch.

Working sample Code:

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

output:

switch1 switch2 select2 d= 2 

output of another run:

switch1 switch2 select1 d= 2 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.