Learning Golang: switch

Share on:

This is part 21 of my journey learning Golang.

Chained conditions

It is a common pattern for a program to have a sequence of conditional statements testing for different values of the same variable or function result.

For instance:

 1package main
 2
 3import (
 4  "fmt"
 5)
 6
 7func main() {
 8  x := 0
 9  y := 0
10  for command := ""; command != "end"; {
11    fmt.Print("Command? ")
12    fmt.Scan(&command)
13    if command == "up" {
14      y -= 1
15    } else if command == "down" {
16      y += 1
17    } else if command == "left" {
18      x -= 1
19    } else if command == "right" {
20      x += 1
21    } else if command == "end" {
22      fmt.Println("Exiting.")
23    } else {
24      fmt.Printf("Invalid command: %v\n", command)
25    }
26    fmt.Printf("x=%v, y=%v\n", x, y)
27  }
28}

Source: learning-go/switch/if-else.go

This program produces an output like this:

 1❯ bin/go run ./switch/if-else.go
 2Command? right
 3x=1, y=0
 4Command? down
 5x=1, y=1
 6Command? right
 7x=2, y=1
 8Command? up
 9x=2, y=0
10Command? left
11x=1, y=0
12Command? back
13Invalid command: back
14x=1, y=0
15Command? end
16Exiting.
17x=1, y=0

Notice the chained if statements testing for different values of command.

The switch statement can be used to simplify code like this and to make the pattern more evident.

switch

The switch statement will execute the statements in the first case expression that matches the value of its operand.

For example:

 1
 2package main
 3
 4import (
 5  "fmt"
 6)
 7
 8func main() {
 9  x := 0
10  y := 0
11  for command := ""; command != "end"; {
12    fmt.Print("Command? ")
13    fmt.Scan(&command)
14    switch command {
15    case "up":
16      y -= 1
17    case "down":
18      y += 1
19    case "left":
20      x -= 1
21    case "right":
22      x += 1
23    case "end":
24      fmt.Println("Exiting.")
25    default:
26      fmt.Printf("Invalid command: %v\n", command)
27    }
28    fmt.Printf("x=%v, y=%v\n", x, y)
29  }
30}

Source: learning-go/switch/switch.go

This program produces an output like this:

 1❯ bin/go run ./switch/switch.go
 2Command? right
 3x=1, y=0
 4Command? down
 5x=1, y=1
 6Command? right
 7x=2, y=1
 8Command? up
 9x=2, y=0
10Command? left
11x=1, y=0
12Command? back
13Invalid command: back
14x=1, y=0
15Command? end
16Exiting.
17x=1, y=0

Notice how each case expression checks for a different value of the same variable (command).

The statements in the default case will be executed if none of the case expressions matched.

Variable case conditions

The value in a case expression does not need to be a constant literal. It can be a variable, or the return value of a function call.

For example:

 1package main
 2
 3import (
 4  "fmt"
 5)
 6
 7func main() {
 8  x := 0
 9  y := 0
10  endCommand := "end"
11  for command := ""; command != endCommand; {
12    fmt.Print("Command? ")
13    fmt.Scan(&command)
14    switch command {
15    case "up":
16      y -= 1
17    case "down":
18      y += 1
19    case "left":
20      x -= 1
21    case "right":
22      x += 1
23    case endCommand:
24      fmt.Println("Exiting.")
25    default:
26      fmt.Printf("Invalid command: %v\n", command)
27    }
28    fmt.Printf("x=%v, y=%v\n", x, y)
29  }
30}

Source: learning-go/switch/switch.go

This program produces an output like this:

1❯ bin/go run ./switch/switch.go
2Command? end
3Exiting.
4x=0, y=0

Notice how instead of checking for the literal "end", the program checks for the value of the endCommand variable.

Summary

The switch statement improves code readability when there is a chain of conditional statements that test for different values of the same variable or function result.

The statements of the first matching case expression will be executed. If no case expression matches, the default statements will be executed, if they are present.


comments powered by Disqus