Table of Contents
In our previous tutorial we learned about decision making using if..else statement in golang. But when you have multiple conditions to evaluate, you’ll find yourself writing a lot of if/else statements. And a bunch of if/else statements makes understanding your code much more difficult. A much shorter way is to use golang switch statement. A switch statement is passed a variable whose value is compared to each case value. When a match is found, the corresponding block of statements is executed.
The switch
 statement is the cleaner and preferred idiomatic approach to writing complex conditional statements in Go.
switch - case statement
Switch statement is used to select one code block among many other code blocks.
Syntax
switch expression {
case conditionX:
Code to execute
case conditionY:
Code to execute
case conditionZ:
Code to execute
default:
Code to execute
}
Explanation
Switch statement works with an expression
 that will be checked against. The expression
is only evaluated once and it is compared with values of each case. If there is a match, the code block associated with the respective case will be executed. In case all the case statements in the switch statement do not match the expression, the default
block will be executed.
Example
In the below example, we define the position variable and assign integer value. The position variable value will be compared against other values in the switch statement. case 1 in the example is executed because position is equal to 1 (position == 1). In case the position does not match with any case in the switch case, the default section will be executed.
package main
import (
"fmt"
)
func main() {
position := 1
switch position {
case 1:
fmt.Println("Gold")
case 2:
fmt.Println("Silver")
case 3:
fmt.Println("Bronze")
default:
fmt.Println("No prices")
}
}
Output
$ go run main.go
Gold
Using “default” in switch case
The switch
statement can include a default case when no other case expressions evaluate to a match. There can only be one default
case and it may be placed anywhere within the switch block. This is similar to the else
condition in an if..else
statement wherein if none of the if
and else if
condition matches, then the flow goes to else
condition. Similarly in switch..case
when none of the case
statement matches the condition, the flow goes to default
.
switch
 block is considered a very good practice. However, as the order of the cases in a switch
 block does matter, the match all remaining cases case should be put last. In Go, the name of the match all remaining cases case is default.In the next example, the position does not match any case in the switch statement. Therefore, the default
case will be executed.
package main
import (
"fmt"
)
func main() {
position := 10
switch position {
case 1:
fmt.Println("Gold")
case 2:
fmt.Println("Silver")
case 3:
fmt.Println("Bronze")
default:
fmt.Println("No prices")
}
}
Output
$ go run main.go
No prices
Using “fallthrough” in switch case statement
There is no automatic fall through in Go's case clause as there is in the C or Java switch statements. Recall that a switch block will exit after executing its first matching case. The code must explicitly place the fallthrough keyword, as the last statement in a case block, to force the execution flow to fall through the successive case block.
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.Here is a simple syntax and example showing the fallthrough
use case. We have defined a variable x
with some value. Now the first case
statement will check if x
is more than 5
. But ir-respective of the fact that this condition is true
or false
, the next case
statement MUST also get called so we explicitly add the keyword fallthrough
so the next case
also gets executed i.e. to check if x is greater than 10
.
package main
import "fmt"
func main() {
x := 56
switch {
case x > 5:
fmt.Println("x is greater than 5")
fallthrough
case x > 10:
// do something else. If x is greater than 10, then the first case will execute first, then this case will follow
fmt.Println("x is greater than 10")
default:
// default case
fmt.Println("Unable to determine value of x")
}
}
Output:
x is greater than 5
x is greater than 10
Matching multiple values in case switch statement
Multi-case switch statement is used when you have multiple values to check against the expression in one case block. The syntax below demonstrates that.
Example
package main
import (
"fmt"
)
func main() {
position := 6
switch position {
case 1:
fmt.Println("Gold")
case 2:
fmt.Println("Silver")
case 3:
fmt.Println("Bronze")
// Matching multiple values
case 4, 5, 6:
fmt.Println("Win prizes worth $8500 each")
// Matching multiple values
case 7, 8, 9, 10:
fmt.Println("Win prizes worth $5000 each")
default:
fmt.Println("No prices")
}
}
Explanation
In the above example, values 4,5,6
are grouped into one case and if the position
value falls between 4 and 6,
this case code block will be executed. Otherwise if the position
value falls between 7,8,9 and 10
, the case will be executed. If all conditions do not match the position value, the default case will be executed.
Output
$ go run main.go
Win prizes worth $8500 each
Terminate case statement execution with “break”
Although the break keyword isn’t required to terminate every case statement, it can be used to end the execution of statements before the end of the case statement is reached:
package main
import (
"fmt"
)
func main() {
product := "Hello WOrld"
for index, character := range product {
switch character {
case 'o', 'O':
if character == 'o' {
fmt.Println("Lowercase o at position", index)
break
}
fmt.Println("Uppercase O at position", index)
case 'd':
fmt.Println("d at position", index)
}
}
}
Here the if
statement checks to see whether the current run has a o
and, if it is, calls the fmt.Println
function and then uses the break
keyword to halt the execution of the case
statement, preventing any subsequent statements from being executed.
Output:
Lowercase o at position 4
Uppercase O at position 7
d at position 10
Switching without condition (Replace if..else with switch..case)
You can also write a switch statement without any condition. Consider the following scenario where you have a variable containing the score of an examination. Based on the score, you want to assign a grade based on the following ranges:
- Less than 50:Â F
- 50 to 59:Â D
- 60 to 69:Â C
- 70 to 79: B
- 80 or higher:Â A
Instead of writing a deck of if/else statements, you can do this using the switch statement without the condition:
package main
import (
"fmt"
)
func main() {
score := 79
grade := ""
switch {
case score < 50: grade = "F"
case score < 60: grade = "D"
case score < 70: grade = "C"
case score < 80: grade = "B"
default: grade = "A"
}
fmt.Println(grade) // B
}
This construct makes it easy to perform conditional checks within the case expressions.
Check substring present in string using switch case
In the previous examples we did a very straight forward conditional checks, but we can also perform regex match to check if a substring exists in a string. Here we have written a go code where we are going to create a regex compiler which will contain some regex to check inside our string. If the match is found then accordingly the case or default statement will be executed:
package main
import (
"fmt"
"regexp"
)
func main() {
asString := "5.00"
// Check if string contains negative number
var negative = regexp.MustCompile(`-`)
// Check if string contains floating number
var floatingPoint = regexp.MustCompile(`\d?\.\d`)
// Check if string contains and email address
var email = regexp.MustCompile(`^[^@]+@[^@.]+\.[^@.]+`)
switch {
// Execute this if string contains negative number
case negative.MatchString(asString):
fmt.Println("Negative number")
// Execute this if string contains floating point
case floatingPoint.MatchString(asString):
fmt.Println("Floating point!")
// Execute this if string contains email address
case email.MatchString(asString):
fmt.Println("It is an email!")
// Execute this if no condition matches
default:
fmt.Println("Something else!")
}
}
Blank switches
There’s another, more powerful way to use switch
 statements. Just like Go allows you to leave out parts from a for statement’s declaration, you can write a switch statement that doesn’t specify the value that you’re comparing against. This is called a blank switch. A regular switch only allows you to check a value for equality.
A blank switch allows you to use any boolean comparison for each case.
package main
import (
"fmt"
)
func main() {
words := []string{"hi", "friend", "hello"}
for _, word := range words {
switch wordLen := len(word); {
case wordLen < 3:
fmt.Println(word, "is a short word!")
case wordLen > 5:
fmt.Println(word, "is a long word!")
default:
fmt.Println(word, "is exactly the right length.")
}
}
}
Output:
hi is a short word!
friend is a long word!
hello is exactly the right length.
Using switch with interface and different data types
The type switch is a statement that uses the Go interface type to compare the underlying type information of values (or expressions). Go offers the type interface{}
, or empty interface, as a super type that is implemented by all other types in the type system. When a value is assigned type interface{}, it can be queried using the type switch, as shown in function tellInterface()
in the following code to query information about its underlying type:
package main
import (
"fmt"
)
// Define different data types
type square struct {
S float64
}
type circle struct {
C float64
}
type rectangle struct {
X float64
Y float64
}
func tellInterface(x interface{}) {
// x.(type) will return the type of x element
switch v := x.(type) {
case square:
fmt.Println("This is a square!")
case circle:
// %v verb used in fmt.Printf() to get the value of the type
fmt.Printf("%v is a circle!\n", v)
case rectangle:
fmt.Println("This is a rectangle!")
default:
fmt.Printf("Unknown type %T!\n", v)
}
}
func main() {
x := circle{C: 10}
tellInterface(x)
y := rectangle{X: 4, Y: 1}
tellInterface(y)
z := square{S: 4}
tellInterface(z)
tellInterface(10)
}
Output:
{10} is a circle!
This is a rectangle!
This is a square!
Unknown type int!
Choosing between “if” and “switch” in golang
As you may already figured out by now that there isn't much different between if and switch in terms of functionality. Both of them are used for decision making and support a series of comparison options. So when should you use switch and when should you go for if..else statements in go programming language?
For example, here I have a small go code written in if..else statement:
package main
import (
"fmt"
"math/rand"
)
var n int
func main() {
if n := rand.Intn(10); n == 0 {
fmt.Println("That's too low")
} else if n > 5 {
fmt.Println("That's too big:", n)
} else {
fmt.Println("That's a good number:", n)
}
fmt.Println(n)
}
If we convert the same to switch case, it would look like:
package main
import (
"fmt"
"math/rand"
)
var n int
func main() {
switch n := rand.Intn(10); {
case n == 0:
fmt.Println("That's too low")
case n > 5:
fmt.Println("That's too big:", n)
default:
fmt.Println("That's a good number:", n)
}
}
So which one of them do you feel looks cleaner and easier to read? Many would agree as the switch case statement.
There is no added advantage of performance or any other factor which choosing either if..else of switch..case but my recommendation is that when you have too many if..else conditions to evaluate then prefer case..switch statement.
You can also check the views from other experts on Go switch vs if-else efficiency
Summary
In this tutorial we covered different examples and methods to use switch case default statement in golang. The switch statement in Go achieves multi-way branching by evaluating values or expressions from case clauses. We also discussed multiple scenarios to use switch case statement by matching a single condition or multiple conditions. We also discussed the difference between using if..else and switch..case statement in golang.
References
Related Keywords: golang switch case multiple conditions, golang switch case string, switch case golang break, golang switch case fallthrough, golang switch case type, golang switch case default, golang switch continue, golang switch empty case