Go言語 switch文

Goでは、switch文を使用してコード実行の複数の分岐を簡潔に処理する方法があります。switch文はif-elseチェーンに代わるもので、一つの値を複数の可能性のある値に対してテストしたいときによく使われます。

Go言語 switch文の構文

以下は、Goにおけるswitch文の構文です。

switch x {
case value1:
    // x == value1のときに、実行されるコード 
case value2:
    // x == value2のときに、実行されるコード
...
default:
    // xがどの値にも一致しない場合に実行されるコード
}

ここで、xは複数の値に対してテストしたい値です。caseキーワードは、テストしたい値を指定するために使用します。xの値がcase文で指定された値に一致する場合、そのcaseの下にあるコードが実行されます。

defaultキーワードは、xがcase文で指定された値のいずれにも一致しない場合に実行されるコードの分岐を指定するために使用します。default分岐は任意ですが、switch文にdefaultを含めるのは良い習慣とされています。

それでは例を見てみましょう。

package main

import "fmt"

func main() {
    i := 0

    switch i {
    case 0:
        fmt.Println("i is 0")
    case 1:
        fmt.Println("i is 1")
    default:
        fmt.Println("x is neither 1 nor 2")
    }
}

この例では、switch文を使って、iの値をcase条件のひとつにマッチさせています。もしiが0なら、プログラムは"i is 0"と出力し、もしiが1に等しければ、プログラムは"i is 1"と出力します。iがどのケースにもマッチしない場合、デフォルトのケースが実行され、プログラムは"x is neither 1 nor 2"を出力します。

switchは次のようにも書けます。

package main

import "fmt"

func main() {
    i := 0

    switch {
    case i == 0:
        fmt.Println("i is 0")
    case i == 1:
        fmt.Println("i is 1")
    default:
        fmt.Println("x is neither 1 nor 2")
    }
}

これはswitch文の変形で、switch部分を省略し、各case条件を直接評価するものです。この場合、プログラムはi == 0とi == 1という式をiの値0に対してテストし、一致するものがあれば対応するケースを実行します。どちらの式にもマッチしない場合,デフォルトのケースが実行され,プログラムは"x is neither 1 nor 2"と出力します。

このように、ifを用いた条件分岐が複雑になる場合、例えば大量のif-else文を記述しないといけないような場合は switch文で記述した方が見通しが良くなるでしょう。

Go言語 複数のcaseの設定

複数のケースブランチを使用して、テストする値を複数指定することができ、各ブランチは複数のステートメントを持つことができます。

package main

import "fmt"

func main() {
    x := 3
    switch x {
    case 1, 2, 3:
        fmt.Println("x is either 1, 2, or 3")
    case 4, 5, 6:
        fmt.Println("x is either 4, 5, or 6")
    default:
        fmt.Println("x is not 1, 2, 3, 4, 5, or 6")
    }
}

switch文は、xの値を、最初のcase文の1, 2, 3の値でテストし、2番目のcase文の4, 5, 6という可能性のある値に対してテストします。xが最初のcase文で指定された値のいずれかに一致する場合、そのcaseの下のコードが実行されます。xがcase文で指定されたどの値にも一致しない場合、デフォルトのブランチの下のコードが実行されます。

他の例も見てみましょう。

package main

import "fmt"

func main() {
    x := "apple"
    switch x {
    case "apple", "banana", "peach":
        fmt.Println("x is a fruit")
    case "carrot", "celery", "beet":
        fmt.Println("x is a vegetable")
    default:
        fmt.Println("x is not a fruit or a vegetable")
    }
}

Go言語 switch文の特徴

Goでは、case式にマッチして対応するコードブロックが実行されると、switch文は終了し、プログラムの流れはswitch文の後に続きます。Javaなどの他のプログラミング言語では、switchのケースから抜け出すためにbreak文が必要ですが、Goではbreak文を使う必要がありません。

このため、Goのスイッチはより簡潔で、現在のcaseがすでにマッチしているにもかかわらず、次のcase文に実行が継続されるという偶発的なフォールスルーのリスクを排除することができます。

以下はJavaのswitch文です。

switch (i) {
    case 0:
        System.out.println("i is 0");
        break;
    case 1:
        System.out.println("i is 1");
        break;
    default:
        System.out.println("x is neither 1 nor 2");
}

Javaのswitchはcaseで評価された後、breakで抜けないと次のcaseが評価される形になっています。

Go言語 switch文のfallthrough

次のcaseブロックを続けて実行したい場合は、明示的にfallthroughをキーワードを使用します。

switch num := 3; num {
case 1:
    println("One")
case 2:
    println("Two")
case 3:
    println("Three")
    fallthrough
case 4:
    println("Four")
default:
    println("Unknown number")
}

この例では、numの値が3であるため、case 3ブロック内のコードが実行されます。次にfallthroughキーワードによって制御が次のcase 4に移るので、そのブロック内のコードも実行されます。

fallthroughキーワードの使用は、あまり一般的ではありません。

この記事を書いた人

著者の画像

Jeffry Alvarado

Ex-Facebook Engineer 大学ではコンピュータサイエンスを専攻し、在学中に複数のインターンシップを経験。コンピュータサイエンスが学習できるプラットフォームRecursionを創業し、CTOとしてカリキュラム作成、ソフトウェア開発を担当。


ツイート