Switch in Go: 6 Ways to Use It
Go is known for being straightforward, but I’ve noticed that not everyone is familiar with how versatile the switch statement can be in this language.
Go is known for being straightforward, but I’ve noticed that not everyone is familiar with how versatile the switch
statement can be in this language.
To start, if you’re new to Go’s switch
statement, it might seem a bit different compared to other languages. Here’s a simple example to show what it looks like:
func main() {
var i int = 1
switch i {
case 1:
fmt.Println("i is 1")
case 2:
fmt.Println("i is 2")
default:
fmt.Println("i is not 1 or 2")
}
}
One cool thing about Go’s switch is that it stops as soon as it finds a match, you don’t need a break statement at the end of each case.
But there’s more to it than just that.
There are two parts in a switch statement in Go: the part before the semicolon is the initializer, and the part after is the value we want to check.
We can choose to use both, one, or none:
switch initializer; value {}
switch initializer {}
switch value {}
switch {}
Interesting, right?
1. Switch with Literal Boolean
Sometimes, you might use a switch
statement with a variable, but here’s a different approach.
Consider using a switch with a literal boolean. This method lets us check multiple conditions without being tied to just one variable’s value:
func main() {
var a int = 1
var b int = 2
switch true { // <--- use true literal
case a == 1 && b == 2:
fmt.Println("a is 1 and b is 2")
case a == 3:
fmt.Println("a is 3"):
default:
fmt.Println("a is not 1 or 3")
}
}
At first glance, switch true
might seem unnecessary and non-sense.
It feels a bit like we’re stating the obvious, but the good news is that Go has a more streamlined way to handle this and you can actually simplify it like this:
switch { // <--- just remove `true`
case a == 1 && b == 2:
...
}
This streamlined approach works just as well.
Also, the switch statement can be used with a `false` literal, offering a way to determine which conditions are not met.
2. Switch short-assignment
Often, we overlook the initializer part in a switch statement.
But it’s quite useful and works similarly to initializers in if
statements or for
loops. It lets you declare and assign a variable, then use it right away.
Here’s an example to illustrate this:
switch a := 1; a {
case 1:
fmt.Println("a is 1")
}
// similar
if a := 1; a == 1 {
fmt.Println("a is 1")
}
In these cases, the scope of a
is limited to the switch statement, meaning you can’t use a outside of it.
Remember how we can ignore both parts of the switch?
Well, you can also choose to use only the initializer part and when you do this, the value part is assumed to be true
:
switch a := 1 {
case a == 1:
fmt.Println("a is 1")
case a == 2:
fmt.Println("a is 2")
}
So far, we’ve seen four ways to structure a switch statement: using only the initializer, only the value, both, or neither. But our focus has been mainly on the switch itself.
Up next, we’ll dive into how the case
part plays a role and how we can make the most of it in our code.
3. Case with multiple values
Yes, the title show the way, you can group multiple values in a single case.
This approach can make your code more concise and easier to read:
switch a := 1; a {
case 1, 2, 3: // <--
fmt.Println("a is 1, 2 or 3")
}
I’ve noticed many newcomers to Go aren’t aware of this capability. Instead, they might write something like this:
switch a := 1; a {
case 1:
case 2:
case 3:
fmt.Println("a is 1, 2 or 3")
}
But this method isn’t quite right because of how switch
works in Go.
In this example, the print statement is only linked with the last case (case 3). So, if a is 1 or 2, nothing will happen because there are no instructions following those cases so the program will just skip over them.
4. Case with fallthrough keyword
This keyword allows the execution to continue to the subsequent case without checking its condition. It’s a bit different from how most languages handle switch cases.
Here’s an example to show how fallthrough
works:
switch a := 1; a {
case 1:
fmt.Println("a is 1")
fallthrough
case 2:
fmt.Println("Now in case 2")
default:
fmt.Println("Neither 1 nor 2")
}
What do you think the output will be?
In this scenario, when a is 1, the program first prints “a is 1”. Then, because of the fallthrough keyword, it immediately fallthrough
the next case (case 2) without checking if a is actually 2. So, it will also print “Now in case 2” too.
You can still put the fallthrough
keyword in the case 2
, the program will continue to the next case (default) and print “Neither 1 nor 2”.
switch a := 1; a {
case 1:
fmt.Println("a is 1")
fallthrough
case 2:
fmt.Println("Now in case 2")
fallthrough
default:
fmt.Println("Neither 1 nor 2")
}
// Output:
// a is 1
// Now in case 2
// Neither 1 nor 2
Keep in mind that the fallthrough
keyword in Go bypasses the condition check of the following case. Therefore, it's not used in the final case of a switch statement, as there's no subsequent case to transition into.
5. Default case and its nuances
The default
case in Go’s switch statement is similar to the else part in an if statement.
It’s the part that runs when none of the other cases match, but here’s something interesting about the default case in Go:
Even though in most programming languages the default
case is usually at the end, in Go, it can be placed anywhere within the switch statement. Most of us put it at the end for clarity, but let’s see what happens when we put it at the beginning:
switch a := 1; a {
default:
fmt.Println("Neither 1 nor 2")
case 1:
fmt.Println("a is 1")
case 2:
fmt.Println("Now in case 2")
}
In this example, even though the default case comes first, it’s still treated as a last resort, only running if no other cases match.
But there’s another layer to explore.
What if we mix the default case with the fallthrough keyword? Let’s check it out:
switch a := 3; a {
default:
fmt.Println("Neither 1 nor 2")
fallthrough
case 1:
fmt.Println("a is 1")
case 2:
fmt.Println("Now in case 2")
}
// Output:
// Neither 1 nor 2
// a is 1
In this scenario, when a is 3, the switch starts with the default case, printing “Neither 1 nor 2”. Then, because of fallthrough, it moves to the next case, which prints “a is 1”.
6. Switch with type assertion
A switch statement can do more than just handle values, it can also work with types. This is particularly useful when dealing with interfaces.
Type assertion is the feature that makes this possible, it lets you check the type of an interface value and run different sections of code depending on what that type is:
func main() {
var i interface{} = "hello"
switch v := i.(type) {
case int:
fmt.Println("i is an int and its value is", v)
case string:
fmt.Println("i is a string and its value is", v)
default:
fmt.Println("Unknown type")
}
}
In this case, i
is an interface variable storing a string.
The switch statement uses i.(type)
to figure out i’s type and then, based on that type, it picks a case to execute:
It checks each case for a specific type (like int or string).
In each case, v represents i’s value as the type checked in that case, so you can use v just like you would use any variable of that type.
And that’s all, you master the switch case in Go now :)
nice