Golang Switch Case Statement: Examples, Multiple Cases, and Type Switch

Tech reviewed: Deepak Prasad
Golang Switch Case Statement: Examples, Multiple Cases, and Type Switch

The switch statement in Go picks one branch from several alternatives. It is the usual tool when you compare one value against many constants, when you want a cleaner boolean ladder than repeated if, or when you need to branch on the concrete type stored in an any or interface value.

For two-way logic, if and else stays fine; when several paths share the same shape, switch usually reads better.

Tested on: Go 1.22 on 64-bit Linux; listings were run with go run while this article was revised.


Quick answer: switch runs one case without falling through

In Go, switch runs the first matching case body and then exits the whole switch. Execution does not continue into the next case unless you use the fallthrough keyword on purpose.

go
package main

import "fmt"

func main() {
	day := "Sunday"
	switch day {
	case "Saturday", "Sunday":
		fmt.Println("Weekend")
	default:
		fmt.Println("Weekday")
	}
}
Output

Running it prints a single line for the matching branch (here the weekend path).


What Is a Switch Statement in Go?

A switch chooses one block to run from several options. It is often clearer than a long if / else if chain when each branch compares the same value or follows the same pattern.

Basic switch case syntax

The form switch expr { case v1: ... case v2: ... default: ... } compares expr to each case value using equality. The default branch runs when nothing else matches.

Why Go switch does not need break

In C-family languages, execution often drops into the next case unless you break. In Go, each case is independent: only the selected case runs, then control leaves the switch. You can still use break to exit the innermost switch early (for example inside a loop); use a label on the outer for and break Label if you need to leave the loop from inside a switch.

This long if chain:

go
package main

import "fmt"

func main() {
	status := "stop"
	if status == "start" {
		fmt.Println("Starting")
	} else if status == "stop" {
		fmt.Println("Stopping")
	} else if status == "restart" {
		fmt.Println("Restarting")
	} else {
		fmt.Println("Unknown command")
	}
}
Output

prints one line for status. The same idea with switch looks like this:

go
package main

import "fmt"

func main() {
	status := "stop"
	switch status {
	case "start":
		fmt.Println("Starting")
	case "stop":
		fmt.Println("Stopping")
	case "restart":
		fmt.Println("Restarting")
	default:
		fmt.Println("Unknown command")
	}
}
Output

Both programs print Stopping for the same status value.


Basic Golang Switch Case Example

Match a single value

go
package main

import "fmt"

func main() {
	day := "Monday"

	switch day {
	case "Monday":
		fmt.Println("Start of the work week")
	case "Friday":
		fmt.Println("Almost weekend")
	case "Saturday", "Sunday":
		fmt.Println("Weekend")
	default:
		fmt.Println("Regular weekday")
	}
}
Output

For day == "Monday" you get the first message only.

Add a default case

default runs when no case matches. It is optional but useful for validation and command parsing.


Use Multiple Values in One Case

List several values separated by commas so they share one body. That is typical for weekends, grouped HTTP status codes, or menu options that behave the same way.

go
package main

import "fmt"

func main() {
	day := "Sunday"

	switch day {
	case "Saturday", "Sunday":
		fmt.Println("Weekend")
	case "Monday", "Tuesday", "Wednesday", "Thursday", "Friday":
		fmt.Println("Weekday")
	default:
		fmt.Println("Invalid day")
	}
}
Output

With day set to Sunday, the weekend branch runs once.


Switch Without an Expression

Write switch { ... } with no value after switch. Each case is a boolean expression; the first true case wins. That replaces many if / else if ladders when the conditions are not all equality on one tag.

Replace long if-else chains

Use conditions directly in case statements

go
package main

import "fmt"

func main() {
	score := 82

	switch {
	case score >= 90:
		fmt.Println("Grade A")
	case score >= 75:
		fmt.Println("Grade B")
	case score >= 60:
		fmt.Println("Grade C")
	default:
		fmt.Println("Fail")
	}
}
Output

For score == 82, the second branch matches and prints the B grade line.


Switch with an Initial Statement

You may declare a short variable in the switch line; it exists only for that switch. That keeps temporary values scoped to the decision.

go
package main

import "fmt"

func main() {
	switch number := 10; {
	case number%2 == 0:
		fmt.Println("Even number")
	default:
		fmt.Println("Odd number")
	}
}
Output

Here number is visible only inside the switch. The program reports that ten is even.


Type Switch in Go

A type switch inspects the dynamic type inside an any (or interface) value. The syntax switch v := x.(type) binds v with the concrete type in each single-type case.

Check the dynamic type of an interface value

go
package main

import "fmt"

func printType(value any) {
	switch v := value.(type) {
	case int:
		fmt.Println("Integer:", v)
	case string:
		fmt.Println("String:", v)
	case bool:
		fmt.Println("Boolean:", v)
	default:
		fmt.Println("Unknown type")
	}
}

func main() {
	printType(100)
	printType("golinuxcloud")
	printType(true)
}
Output

You should see three lines, one per call, labeling integer, string, and boolean.

Handle multiple types in one type switch

When several concrete types should share logic, list them in one case. The switch form switch value.(type) (without a binding) is enough when you do not need a typed variable per branch.

go
package main

import "fmt"

func check(value any) {
	switch value.(type) {
	case int, int64, float64:
		fmt.Println("Numeric value")
	case string:
		fmt.Println("String value")
	default:
		fmt.Println("Other value")
	}
}

func main() {
	check(10)
	check("hello")
	check(true)
}
Output

The three calls print numeric, string, and other in order.


fallthrough in Go Switch

Go does not enter the next case after a match. If you truly need the next case body to run as well, end the case with fallthrough. It continues without re-checking the next case condition, so it is easy to misuse.

When fallthrough is allowed

fallthrough is only for value switches, not type switches. It must be the last statement in the case block.

go
package main

import "fmt"

func main() {
	number := 1

	switch number {
	case 1:
		fmt.Println("One")
		fallthrough
	case 2:
		fmt.Println("Two")
	case 3:
		fmt.Println("Three")
	}
}
Output

You get One followed by Two because execution drops into the next case after fallthrough.

Why fallthrough should be used carefully

Prefer comma-separated cases when both branches would print the same kind of work:

go
package main

import "fmt"

func main() {
	switch number := 2; number {
	case 1, 2:
		fmt.Println("One or Two")
	case 3:
		fmt.Println("Three")
	}
}
Output

That prints the combined branch once without fallthrough.


Common Switch Statement Use Cases

Match command-line options

go
package main

import "fmt"

func main() {
	command := "start"

	switch command {
	case "start":
		fmt.Println("Starting service")
	case "stop":
		fmt.Println("Stopping service")
	case "restart":
		fmt.Println("Restarting service")
	default:
		fmt.Println("Unknown command")
	}
}
Output

Handle HTTP status codes

go
package main

import "fmt"

func main() {
	statusCode := 404

	switch statusCode {
	case 200:
		fmt.Println("OK")
	case 400:
		fmt.Println("Bad request")
	case 401, 403:
		fmt.Println("Unauthorized or forbidden")
	case 404:
		fmt.Println("Not found")
	case 500:
		fmt.Println("Server error")
	default:
		fmt.Println("Unhandled status code")
	}
}
Output

Check weekdays and weekends

go
package main

import "fmt"

func main() {
	day := "Saturday"

	switch day {
	case "Saturday", "Sunday":
		fmt.Println("Weekend")
	default:
		fmt.Println("Weekday")
	}
}
Output

Classify numbers with a tagless switch

go
package main

import "fmt"

func main() {
	n := -5

	switch {
	case n < 0:
		fmt.Println("Negative")
	case n == 0:
		fmt.Println("Zero")
	default:
		fmt.Println("Positive")
	}
}
Output

break and labeled break in a loop

Inside a switch, break exits the innermost switch, not an outer for. Use a label on the loop when you need to stop the loop from inside a case.

go
package main

import "fmt"

func main() {
Outer:
	for i := 0; i < 5; i++ {
		switch {
		case i == 2:
			fmt.Println("break outer at", i)
			break Outer
		default:
			fmt.Println("i=", i)
		}
	}
	fmt.Println("done")
}
Output

The loop exits when i reaches two, then done prints.


Common Mistakes with Go Switch

Expecting automatic fallthrough

Only the matching case runs. If n is 1, a value switch with case 1: and case 2: does not run case 2 unless you add fallthrough.

Using fallthrough when multiple values fit better

Prefer case "Saturday", "Sunday": instead of chaining fallthrough across weekend cases.

Using fallthrough in a type switch

The compiler rejects fallthrough in a type switch. Split types or share logic with helper functions instead.

Ordering cases in a tagless switch

Cases are evaluated top to bottom; the first true branch wins. Put stricter conditions first.

go
package main

import "fmt"

func main() {
	score := 95

	switch {
	case score >= 90:
		fmt.Println("Excellent")
	case score >= 60:
		fmt.Println("Pass")
	default:
		fmt.Println("Fail")
	}
}
Output

If you swap the two threshold cases, a score of 95 would hit the weaker test first and never reach Excellent.

Growing a switch without bound

Very large switches get hard to review. When each case maps to independent behavior, consider a map of handlers, small functions, or types that implement a shared interface.


Go Switch Cheat Sheet

Goal Pattern Example idea
Match one expression switch v { case ... } switch cmd { case "start": ... }
Several constants, same body Comma-separated case "Sat", "Sun":
Fallback default default: fmt.Println("unknown")
Boolean ladder Tagless switch { ... } switch { case x > 10: ... }
Scoped setup Initial statement switch x := f(); x { ... }
Dynamic type Type switch switch v := x.(type) { case int: ... }
Force next case body fallthrough Rare; document why

Which switch pattern should you use?

  • One comparable value and many constants: classic switch value.
  • Unrelated boolean tests: switch { case cond: }.
  • Behavior depends on concrete type inside any: type switch.
  • Two or three branches: if / else is often enough.

Summary

Go’s switch covers golang switch case style questions in one construct: match a value with case and default, combine values with commas, write tagless switches for ranges and scores, add a short declaration before the tag when it helps, and use switch v := x.(type) for dynamic types. Cases do not fall through by default, so you rarely need break; use fallthrough only when the control flow is obvious to the next reader. Order tagless cases from specific to general, and refactor very large switches into maps or helpers when cases stop fitting on one screen.


References


Frequently Asked Questions

1. Does Go switch need break?

No. Cases do not fall through automatically, so the matching case runs once and then the switch ends unless you use fallthrough.

2. Can a Go switch case have multiple values?

Yes. List them separated by commas in one case: case "Sat", "Sun":.

3. Can switch work without a condition in Go?

Yes. Use switch { case booleanExpr: ... } so each case is a boolean expression; the first true case runs.

4. What is the difference between switch and if-else in Go?

Use switch when many branches compare the same expression or when a tagless switch reads clearer than a long if-else chain; use if for a small number of unrelated conditions.

5. What is a type switch in Go?

A type switch uses switch v := x.(type) to branch on the concrete type stored in an interface or any value.

6. What does fallthrough do in Go?

fallthrough forces execution to continue into the next case body without re-testing that case match; use sparingly.

7. Is fallthrough allowed in a type switch?

No. The language forbids fallthrough in type switches.

8. Does Go fall through to the next case by default?

No. Only the selected case runs unless you end it with the fallthrough keyword.
Deepak Prasad

R&D Engineer

Founder of GoLinuxCloud with over a decade of expertise in Linux, Python, Go, Laravel, DevOps, Kubernetes, Git, Shell scripting, OpenShift, AWS, Networking, and Security. With extensive experience, he excels across development, DevOps, …

  • Red Hat Certified System Administrator in Red Hat OpenStack
  • Certified Kubernetes Application Developer (CKAD)
  • Red Hat Certified Specialist in Ansible Automation
  • Go (programming language)
  • Python (programming language)
  • DevOps
  • Computer Security