3.3 Make Better Choices in Go with switch
TL;DR
- A
switchstatement is a clean way to handle multiple choices, like a tidier version of a longif-elsechain. - It checks a single value or expression against a list of possible
cases. - The
defaultcase is a safety net that runs if no othercasematches. - A special "type switch" lets you check what kind of data a variable holds (e.g., text, number, etc.).
Why This Matters
Have you ever written code that feels like a giant tangled knot of if this, else if that, else if another thing...? It gets messy fast. When you have to check one variable against many possible options, this pattern becomes hard to read and even harder to fix.
The switch statement is Go's elegant solution to this problem. Think of it as a well-organized menu. Instead of asking a series of yes/no questions, you present one item (the variable) and let the program jump directly to the correct option (case). This makes your code cleaner, more readable, and less likely to hide bugs.
Concepts in Plain English
Before we dive in, let's get a few key ideas straight. They're simpler than they sound.
switchStatement: This is our main tool. It's like a traffic controller that looks at one car (a variable) and directs it down one of several possible roads (cases).case: A specific path or option. If the variable matches thecase's value, the code inside thatcaseruns. It's like one of the destinations on a road sign.default: The "none of the above" option. If the variable doesn't match any othercase, thedefaultcode runs. It's the road for "all other traffic."- Type Switch: A special kind of
switchthat doesn't care about the value of a variable, but its data type. It’s like a sorting machine at a recycling plant that separates plastic, glass, and paper into different bins.
Here’s a quick reference table.
| Term | Simple Definition | Where It Shows Up |
switch | The start of a choice-making block. | switch myVariable { ... } |
case | A single option to check against. | case "admin": |
default | The fallback option if no cases match. | default: |
.(type) | Special syntax used only in a type switch. | switch v := i.(type) { ... } |
Quick Setup
You don't need to install anything to try these examples! You can run all the code snippets directly in your browser using the official Go Playground. Just copy, paste, and hit the "Run" button.
Do It Step by Step
Let's build a switch statement from the ground up. We'll cover two main scenarios: checking for a specific value and checking for a condition.
Part 1: The Basic switch for Checking Values
This is the most common use of switch. We have a variable and want to do different things based on its exact value.
Goal: Write a program that prints a message based on a user's role.
- Input → Output:
- If
userRoleis"viewer", the output is:View-only access. - If
userRoleis"admin", the output is:Full access granted.
- If
Add a default case.This is our safety net. It runs if userRole is anything other than "admin" or "editor".
package main
import "fmt"
func main() {
userRole := "viewer" // Try changing this to "admin" or "editor"!
switch userRole {
case "admin":
// This code runs ONLY if userRole is "admin"
fmt.Println("Full access granted.")
case "editor":
// This code runs ONLY if userRole is "editor"
fmt.Println("Can write and publish content.")
default:
// This code runs for any other value
fmt.Println("View-only access.")
}
}
Add your cases.Each case represents a possible value for userRole. We'll add options for "admin" and "editor".
switch userRole {
case "admin":
// This code runs ONLY if userRole is "admin"
fmt.Println("Full access granted.")
case "editor":
// This code runs ONLY if userRole is "editor"
fmt.Println("Can write and publish content.")
}
Start with switch and the variable.We'll check a variable named userRole.
// The variable we want to check
userRole := "editor"
// Start the switch statement on that variable
switch userRole {
// ... cases go here
}
Pro Tip — In Go, you don't need to add abreakat the end of eachcaselike in some other languages. It automatically stops after a match, which prevents a lot of common bugs!
Part 2: The Conditional switch
Sometimes you don't want to check for an exact value, but for a condition (e.g., is a number greater than 100?). For this, we use a switch without a variable next to it.
Goal: Convert a numeric score into a letter grade.
- Input → Output:
- If
scoreis85, the output is:Grade: B - The condition
score >= 90is checked and isfalse. - The condition
score >= 80is checked and istrue. This block runs, and theswitchends.
- If
Write cases with expressions.Each case will now be a condition that results in true or false. Go will pick the first one that is true.
package main
import "fmt"
func main() {
score := 85 // Try changing this score!
switch {
case score >= 90:
// Runs if score is 90 or higher
fmt.Println("Grade: A")
case score >= 80:
// Runs if score is NOT >= 90, but IS >= 80
fmt.Println("Grade: B")
case score >= 70:
// Runs if score is NOT >= 80, but IS >= 70
fmt.Println("Grade: C")
default:
// Runs for any score below 70
fmt.Println("Grade: F")
}
}
Start with a "naked" switch.This time, we just write switch followed by an opening brace {.
score := 85
// No variable here!
switch {
// ... cases with conditions go here
}
Here’s a table to help you decide which switch form to use.
| Switch Type | When to Use It | Example |
switch variable { ... } | When you are checking one variable for several specific, exact values. | switch httpStatus { case 200: ... case 404: ... } |
switch { ... } | When you need to check a series of conditions or ranges. | switch { case temperature > 30: ... case temperature < 0: ... } |
Examples Section
Let's look at two practical examples you might see in the wild.
Example A: Minimal Traffic Light
This is a classic switch that controls program flow based on a simple state.
package main
import "fmt"
func getActionForLight(color string) string {
var action string
switch color {
case "red":
action = "Stop"
case "yellow":
action = "Prepare to stop"
case "green":
// You can combine multiple cases!
case "blinking green":
action = "Go"
default:
action = "Unknown light color"
}
return action
}
func main() {
fmt.Println("Light is red. Action:", getActionForLight("red"))
fmt.Println("Light is green. Action:", getActionForLight("green"))
}
This code defines a function that returns a specific action string based on the traffic light's color. Notice how "green" and "blinking green" are combined into one case to produce the same result.
Example B: The "What Am I?" Type Switch
Sometimes a function receives data and doesn't know its exact type. A type switch is the perfect tool for safely figuring it out.
package main
import "fmt"
// This function accepts any kind of data
func printDetails(value interface{}) {
fmt.Printf("The value is '%v'. ", value)
// A type switch figures out what the actual type is
switch v := value.(type) {
case string:
// Inside this case, 'v' is known to be a string
fmt.Printf("It's a string of length %d.\n", len(v))
case int:
// Inside this case, 'v' is known to be an integer
if v > 100 {
fmt.Println("It's a large integer.")
} else {
fmt.Println("It's an integer.")
}
default:
// For any other type
fmt.Printf("It's a type I don't recognize: %T.\n", v)
}
}
func main() {
printDetails("hello")
printDetails(42)
printDetails(999)
printDetails(true) // This will hit the default case
}
The interface{} type is Go's way of saying "this can be anything." The switch v := value.(type) syntax is special: it checks the type of value and also puts the correctly-typed value into a new variable v that you can use inside each case.
Here is a diagram showing how that logic flows:
flowchart LR
subgraph Type Switch Logic
A[Start with a variable `value`] --> B{What is the type of `value`?};
B -->|It's a `string`| C[Run string-specific code];
B -->|It's an `int`| D[Run integer-specific code];
B -->|It's something else| E[Run default code];
C --> F[End];
D --> F[End];
E --> F[End];
end
ASCII Fallback: The diagram shows a variable named value entering a decision block. Based on its type (string, integer, or other), it follows a different path to execute type-specific code, after which the process concludes.
Common Pitfalls
- Forgetting the
defaultcase. If your variable could have an unexpected value and you don't have adefault, your program might just do nothing, which can be confusing. Always add adefaultas a safety net. - Order matters in conditional
switches. In aswitch { ... }block, Go runs the firstcasethat is true and stops. If you putcase score >= 70:beforecase score >= 90:, a score of 95 would incorrectly be graded as a "C". - Mixing up
casevalues. Aswitchchecks for equality.case "5":(text) is not the same ascase 5:(a number). This can lead to your code taking thedefaultpath when you don't expect it to.
FAQ
- Q: Can I match multiple values in one
case?- A: Yes! Just separate them with a comma:
case "Saturday", "Sunday": fmt.Println("It's the weekend!").
- A: Yes! Just separate them with a comma:
- Q: What’s the real difference between
switchand a bunch ofif-elsestatements?- A: Readability. For checking a single variable against many distinct values,
switchis much cleaner and clearly states your intent.if-elseis better for checking different, unrelated conditions.
- A: Readability. For checking a single variable against many distinct values,
- Q: Does the order of
cases matter?- A: Absolutely. Go checks them from top to bottom and stops at the first match. This is especially important for conditional
switches that check ranges.
- A: Absolutely. Go checks them from top to bottom and stops at the first match. This is especially important for conditional
- Q: What exactly does
v := value.(type)do?- A: It's a special form, only for type switches. It does two things at once: 1) it checks the data type of the interface
value, and 2) it creates a new variablevthat has the correct, specific type, which you can then use inside thecaseblock.
- A: It's a special form, only for type switches. It does two things at once: 1) it checks the data type of the interface
Recap
You've learned how to use switch to make your code much cleaner and more organized.
switchis your go-to tool for replacing messyif-else if-elsechains.- Use a basic
switchto check a variable against a list of specific values. - Use a conditional
switch(with no variable) to check a list of boolean conditions. - Use a type
switchto find out the data type of a variable and act on it safely. - Your next step? Find a messy
if-elseblock in your code and try rewriting it as aswitch!