Go by Example

Switch

Switch expressions with no fall-through, multi-value cases, init statements, and type switches for interface dispatch.

Go's switch statement does not fall through by default - each matched case runs and exits. This removes a whole class of bugs common in C and Java. Cases can match multiple values, and a switch with no expression works like an if/else if chain.

Basic switch on a value. No break needed - Go exits automatically after each case body.

package main
 
import "fmt"
 
func main() {
    day := "Monday"
 
    switch day {
    case "Saturday", "Sunday":
        fmt.Println("weekend")
    case "Monday":
        fmt.Println("start of week")
    default:
        fmt.Println("weekday")
    }
    // start of week
}

A switch without an expression is equivalent to switch true - cases contain boolean conditions, just like if/else if but more readable for multiple branches.

package main
 
import "fmt"
 
func main() {
    n := 42
 
    switch {
    case n < 0:
        fmt.Println("negative")
    case n == 0:
        fmt.Println("zero")
    case n < 100:
        fmt.Println("small positive")
    default:
        fmt.Println("large positive")
    }
    // small positive
}

A type switch dispatches on the dynamic type of an interface value. The variable in the case clause is re-bound to the concrete type inside each branch.

package main
 
import "fmt"
 
func describe(i interface{}) string {
    switch v := i.(type) {
    case int:
        return fmt.Sprintf("int: %d", v)
    case string:
        return fmt.Sprintf("string: %q", v)
    case bool:
        return fmt.Sprintf("bool: %t", v)
    default:
        return fmt.Sprintf("unknown: %T", v)
    }
}
 
func main() {
    fmt.Println(describe(42))      // int: 42
    fmt.Println(describe("hello")) // string: "hello"
    fmt.Println(describe(true))    // bool: true
}

In production

Type switches are idiomatic Go for interface dispatch - cleaner than a chain of type assertions with ok-checking. They are the primary tool for polymorphism in codebases that avoid deep interface hierarchies. If you need fall-through behaviour (rare), use the explicit fallthrough keyword; it must be the last statement in the case body and it skips the condition check on the next case.

Enjoyed this? Get more essays on software craft delivered to your inbox.

Subscribe free