golang_switch

Golang switch

Golang switch

switch

Like many C-derived languages, Go has a switch statement. Most developers in those languages avoid switch statements because of their limitations on values that can be switched on and the default fall-through behavior. But Go is different. It makes switch statements useful.

Note

For those readers who are more familiar with Go, we’re going to cover expression switch statements in this chapter. We’ll discuss type switch statements when we talk about interfaces in Chapter 7.

At first glance, switch statements in Go don’t look all that different from how they appear in C/C++, Java, or JavaScript, but there are a few surprises. Let’s take a look at a sample switch statement. You can run the code in Example 4-19 on The Go Playground.

Example 4-19. The switch statement

words := []string{“a”, “cow”, “smile”, “gopher”, “octopus”, “anthropologist”} for _, word := range words { switch size := len(word); size { case 1, 2, 3, 4: fmt.Println(word, “is a short word!”) case 5: wordLen := len(word) fmt.Println(word, “is exactly the right length:”, wordLen) case 6, 7, 8, 9: default: fmt.Println(word, “is a long word!”) } }

When we run this code, we get the following output:

a is a short word! cow is a short word! smile is exactly the right length: 5 anthropologist is a long word!

Let’s go over the features of the switch statement to explain the output. As is the case with if statements, you don’t put parenthesis around the value being compared in a switch. Also like an if statement, you can declare a variable that’s scoped to all of the branches of the switch statement. In our case, we are scoping the variable word to all of the cases in the switch statement.

All of the case clauses (and the optional default clause) are contained inside a set of braces. But you should note that you don’t put braces around the contents of the case clauses. You can have multiple lines inside a case (or default) clause and they are all considered to be part of the same block.

Inside case 5:, we declare wordLen, a new variable. Since this is a new block, you can declare new variables within it. Just like any other block, any variables declared within a case clause’s block are only visible within that block.

If you are used to putting a break statement at the end of every case in your switch statements, you’ll be happy to notice that they are gone. By default, cases in switch statements in Go don’t fall through. This is more in line with the behavior in Ruby or (if you are an old-school programmer) Pascal.

This prompts the question: if cases don’t fall through, what do you do if there are multiple values that should trigger the exact same logic? In Go, you separate multiple matches with commas, like we do when matching 1, 2, 3, and 4 or 6, 7, 8, and 9. That’s why we get the same output for both a and cow.

Which leads to the next question: if you don’t have fall-through, and you have an empty case (like we do in our sample program when the length of our argument is 6, 7, 8, or 9 characters), what happens? In Go, an empty case means nothing happens. That’s why we don’t see any output from our program when we use octopus or gopher as the parameter.

Tip

For the sake of completeness, Go does include a fallthrough keyword, which lets one case continue on to the next one. Please think twice before implementing an algorithm that uses it. If you find yourself needing to use fallthrough, try to restructure your logic to remove the dependencies between cases.

In our sample program we are switching on the value of an integer, but that’s not all you can do. You can switch on any type that can be compared with ==, which includes all of the built-in types except slices, maps, channels, functions, and structs that contain fields of these types.

Even though you don’t need to put a break statement at the end of each case clause, you can use them in situations where you want to exit early from a case. However, the need for a break statement might indicate that you are doing something too complicated. Consider refactoring your code to remove it.

There is one more place where you might find yourself using a break statement in a case in a switch statement. If you have a switch statement inside a for loop, and you want to break out of the for loop, put a label on the for statement and put the name of the label on the break. If you don’t use a label, Go assumes that you want to break out of the case. Let’s look at a quick example. You can run the code in Example 4-20 on The Go Playground.

Example 4-20. The case of the missing label

func main() { for i := 0; i < 10; i++ { switch { case i%2 == 0: fmt.Println(i, “is even”) case i%3 == 0: fmt.Println(i, “is divisible by 3 but not 2”) case i%7 == 0: fmt.Println(“exit the loop!”) break default: fmt.Println(i, “is boring”) } } }

Running this code produces the following output:

0 is even 1 is boring 2 is even 3 is divisible by 3 but not 2 4 is even 5 is boring 6 is even exit the loop! 8 is even 9 is divisible by 3 but not 2

That’s not what we intended. The goal was to break out of the for loop when we got a 7. To do this, we need to introduce a label, just like we did when breaking out of a nested for loop. First, we label the for statement:

loop: for i := 0; i < 10; i++ {

Then we use the label on our break:

break loop

You can see these changes on The Go Playground. When we run it again, we get the output that we expected:

0 is even 1 is boring 2 is even 3 is divisible by 3 but not 2 4 is even 5 is boring 6 is even exit the loop!

golang_switch.txt · Last modified: 2025/02/01 06:54 by 127.0.0.1

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki