Why isn't fallthrough allowed in a type switch?


I’m wondering why fallthrough isn’t allowed in a type switch statement in golang.

According to the specification: “The “fallthrough” statement is not permitted in a type switch.”, which doesn’t explain much about WHY it isn’t allowed.

The code attached is to simulate a possible scenario were a fallthrough in a type switch statement might have been useful.

Notice! This code doesn’t work, it will produce the error: “cannot fallthrough in type switch”. I’m just wondering what possible reasons might have been for not allowing the fallthrough statement in a type switch.

//A type switch question
package main

import "fmt"

//Why isn't fallthrough in type switch allowed?
func main() {
    //Empty interface
    var x interface{}

    x = //A int, float64, bool or string value

    switch i := x.(type) {
    case int:
        fmt.Println(i + 1)
    case float64:
        fmt.Println(i + 2.0)
    case bool:
    case string:
        fmt.Printf("%v", i)
        fmt.Println("Unknown type. Sorry!")


How would you expect fallthrough to work? In this type switch, the i variable has a type that depends on the particular case that’s invoked. So in the case bool the i variable is typed as bool. But in case string it’s typed as string. So either you’re asking for i to magically morph its type, which isn’t possible, or you’re asking for it to be shadowed by a new variable i string, which will have no value because its value comes from x which is not, in fact, a string.

Here’s an example to try and illustrate the problem:

switch i := x.(type) {
case int:
    // i is an int
    fmt.Printf("%T\n", i); // prints "int"
case bool:
    // i is a bool
    fmt.Printf("%T\n", i); // prints "bool"
case string:
    fmt.Printf("%T\n", i);
    // What does that type? It should type "string", but if
    // the type was bool and we hit the fallthrough, what would it do then?

The only possible solution would be to make the fallthrough cause the subsequent case expression to leave i as an interface{}, but that would be a confusing and bad definition.

If you really need this behavior you can already accomplish this with the existing functionality:

switch i := x.(type) {
case bool, string:
    if b, ok := i.(bool); ok {
        // b is a bool
    // i is an interface{} that contains either a bool or a string

Answered By – Lily Ballard

Answer Checked By – Candace Johnson (GoLangFix Volunteer)

Leave a Reply

Your email address will not be published.