Menu

Go言語のswitch文:fallthroughと複数の値

Goのswitchの仕組みを解説します。caseはデフォルトでフォールスルーせず、1つのcaseに複数の値を並べられ、条件のないswitchはif/elseの連鎖の代わりになります。初期化文付きのswitch、fallthroughキーワード、型スイッチの概要も扱います。

このページのコードはエディタで実行できます - 編集してすぐに結果を確認できます。

switch は1つの値をcaseのリストと比べ、最初に一致したものを実行します。C、Java、JavaScriptと違って、Goのcaseは次のcaseに フォールスルーしない ので、break を書き忘れることもありません。

caseは上から下へチェックされ、最初に一致したcaseだけが実行されます。default は何も一致しないときに実行されます。省略でき、リストのどこに置いても構いませんが、慣習では最後に置きます。

caseごとの複数の値

case "sat", "sun": はどちらの値にも一致します。Cが空のcaseを積み重ねて表すことを、Goはこう書きます。比較可能な型なら何でも使えます。文字列、数値、ルーン、真偽値、ポインタ、そして列挙型のような名前付きの型です。

同じ定数値を持つ2つのcaseはコンパイルエラーになります。

./main.go:10:7: duplicate case 1 (constant of type int) in expression switch
	./main.go:8:7: previous case

条件のないswitch

式を省略すると、各caseが真偽値のテストになります。これは長い if/else if の連鎖を、Goでよりすっきり書いた形です。

switch {switch true { の省略形です。最初に真になったcaseが勝つので、順序が重要です。bmi < 25 に到達するのは bmi < 18.5 が偽だったときだけなので、各caseは上のcaseが失敗したことを前提にできます。

初期化文付きのswitch

if と同じく、switch も短い文から始められます。そこで宣言した変数のスコープはswitchの中だけです。

初期化文は条件のないswitchと組み合わせることもできます:switch n := len(items); { case n == 0: ... }

fallthrough

次のcaseに実行を続けたいときは、caseの最後の文として fallthrough を書きます。これは 条件を評価せずに 次のcaseの本体に制御を移します。

レベル2では write の次に read が表示され、権限が下に向かって積み重なります。後のcaseの条件はチェックされません。case 2 から fallthrough した後は、level が2であっても case 1 が実行されます。

fallthrough のルールは次のとおりです。

  • caseの最後の文でなければならない。
  • 最後のcaseには書けない:cannot fallthrough final case in switch
  • 型スイッチでは使えない。

実際のGoのコードで fallthrough を見ることはまれです。caseごとの複数の値でよくある用途はまかなえますし、fallthroughの連鎖より明示的な関数呼び出しのほうがたいてい明快です。

switchの中のbreak

case内の breakswitch を抜けます。caseは自然に終わるので、必要になるのはcaseを途中で抜けるときだけです。罠になるのは、ループの中の switch です。

loop ラベルがないと、break はswitchを終わらせるだけで、ループは "c" へと続きます。一方 continue は、switch がループではないので、常に外側のループを指します。

型によるswitch

型スイッチは、特別な形 v.(type) を使って、インターフェースの値の動的な型で分岐します。

型が1つだけのcaseでは、x はその型になります(string のcaseでは len(x) が使えます)。複数の型を並べたcaseでは、x はインターフェース型のままです。型スイッチと v.(T) のアサーションは型アサーションのページで詳しく扱っています。

Goのswitchが違うところ

挙動C、Java、JavaScriptGo
次のcaseへの流れ込みデフォルトfallthrough のときだけ
各caseの最後の break必須不要
caseごとの複数の値空のcaseを積み重ねるcase a, b, c:
caseの値(ほとんど)定数任意の式、上から順に評価
switchの値整数型(C)比較可能な任意の型
switchの式がない使えないswitch { case cond: }

caseの式は定数である必要はありません。case limit(), max + 1: も正しいコードです。一致するまで順に評価されるので、後ろの式は一度も実行されないこともあります。

網羅性

Goは、列挙型に対するswitchがすべての値を網羅しているかをチェックしません。想定外の値に対してログを出す、エラーを返す、またはpanicする default を加えるか、exhaustive リンター(golangci-lint の一部)を使って、漏れたcaseをビルド時に報告させます。

よくある質問

Goのswitchは次のcaseにフォールスルーしますか?

しません。Goのcaseは次の case のところで自動的に終わり、止めるために break を書くことはありません。次のcaseの本体に実行を続けたい場合は、caseの最後の文として fallthrough を書きます。これは次のcaseの条件をチェックせずに無条件でジャンプします。

Goで1つのcaseに複数の値をマッチさせるには?

カンマで区切って並べます:case "sat", "sun":。switchの値がそのどれかと等しければ、そのcaseが実行されます。CやJavaで空のcaseを積み重ねていた書き方の代わりになります。

Goの条件のないswitchとは何ですか?

switch { case x < 0: ...; case x == 0: ...; default: ... } です。switch の後に式がないと、各caseは真偽値の条件になり、最初に真になったものが実行されます。長い if/else if の連鎖の代わりとなるGoらしい書き方です。

Goのswitchの中のbreakは何をしますか?

外側の for ループではなく switch を終わらせます。caseは自然に終わるのでめったに必要ありませんが、ループ内のswitchで break を書いてループを抜けられると思った人は驚きます。ループを抜けるには、ラベル付きの breakreturn を使います。

Coddy programming languages illustration

Coddyでコードを学ぼう

始める