Go switch
The switch
statement evaluates an expression and matches the expression's value against a series of case
clauses and executes the matching case statement.
Unlike other programming languages the break
statement is not required at the end of each case
as its automatically provided in Go. Another important difference is that Go's switch
cases need not be constants, and the values involved need not be integers
The switch
instruction
Sometimes a lot of if
statements can be replaced by a switch
instruction to make the code more readable.
It is especially true when you want to match a variable against multiple values.
As an example, the following code
func printNumber(n int) {
if n == 1 {
fmt.Println("one")
} else if n == 2 {
fmt.Println("two")
} else if n == 3 {
fmt.Println("three")
} else {
fmt.Println("other")
}
}
could be written like this:
func printNumber(n int) {
switch n {
case 1:
fmt.Println("one")
case 2:
fmt.Println("two")
case 3:
fmt.Println("three")
default:
fmt.Println("other")
}
}
where default
is the default case, that is executed if none of the other cases match.
You might also think of a game where you need to run different code depending on the key pressed by the user.
switch key := getKey(); key {
case "up":
// move the player up
case "down":
// move the player down
// etc.
}
The key := getKey()
is a short variable declaration, that is executed before the switch
instruction.
Complete example
Let's say that we want to write a function that computes the area of a shape given its name.
package main
import (
"fmt"
"math"
)
func area(shape string, params ...float32) float32 {
switch shape {
case "circle":
radius := params[0]
return math.Pi * radius * radius
case "rectangle":
width := params[0]
height := params[1]
return width * height
}
return 0.0 // unknown shape
}
func main() {
fmt.Println("Aread of Circle:", area("circle", 3))
fmt.Println("Aread of Rectangle:", area("rectangle", 5, 7))
}
Output
Aread of Circle: 28.274334
Aread of Rectangle: 35
We assume that params
contains either:
- the radius of the circle,
- the width and the height of the rectangle.
There are better ways to write this function, for example by using structures but we will see that later.
The fallthrough
keyword
The fallthrough
keyword can be used to execute the code of the next case, whether or not the condition is true. It has to be the last instruction of the case.
package main
import "fmt"
func main() {
n := 1
switch n {
case 0:
fmt.Println("n is zero")
fallthrough
case 1:
fmt.Println("n is one or zero")
fallthrough
case 2:
fmt.Println("n is two, one or zero")
}
}
Output
n is one or zero
n is two, one or zero
If the variable n
is equal to 0
, the first condition is true and the code of the first case is executed.
Then, thanks to the fallthrough
keyword, the code of the second case is executed, and similarly for the third case.
Multiple cases
Another interesting feature of the switch
instruction is that you can have multiple cases in the same block.
package main
import "fmt"
func main() {
month := "October"
switch month {
case "January", "March", "May", "July", "August", "October", "December":
fmt.Println("31 days")
case "April", "June", "September", "November":
fmt.Println("30 days")
case "February":
fmt.Println("28 or 29 days")
}
}
Output
31 days
Without this syntax, we would have to write a new case
for each month.
Empty expression
Finally, the switch
instruction can be used without an expression, in which case it is equivalent to a switch true
instruction.
package main
import "fmt"
func main() {
n := -45
switch {
case n < 0:
fmt.Println("n is negative")
case n > 0:
fmt.Println("n is positive")
default:
fmt.Println("n is zero")
}
}
Output
n is negative
Here, n
is a variable that is defined outside of the switch
instruction.