Go言語の switch 文

ここでは Go 言語の switch 文について説明します。

Go の switch 文の基本

switch 文はある値を評価して、その値ごとに処理を分岐させるために使います。

条件による分岐という意味では、if 文でも同様の処理の分岐を行うことは可能です。しかし通常、 たくさんの分岐があり、それぞれの分岐毎の処理が少ない場合などに、switch 文が使われます。

switch 文の基本的な使い方は次の通りです。

switch m {
case 0:
	// m が 0 の時
case 1:
	// m が 1 の時
default:
	// その他の場合
}

switch というキーワードに続けて、評価対象となる変数を指定します。この場合変数 m の値によって処理が分岐します。 m の値が case キーワードに続く値の場合に、そのセクションが実行されます。例えば m の値が 0 である場合は、 case 0: から始まる箇所が実行されます。

他の言語で多くみられるような、case の処理を区切る break は不要です。Go では既定でフォールスルーしません。

default: はいずれの case にも該当しない場合に実行されます。 default は任意です。なくても構いません。

それでは、次の例を見てみましょう。次の例を実行するとどのような出力になるでしょうか。

ここでは for 文で変数 m に値を 0 から 8 まで順に渡し、 switch 文の処理を繰り返しています。

package main

import (
	"fmt"
)

func main() {
	for m := 0; m < 9; m++ {
		switch m {
		case 0, 1, 2: // 値を複数指定
			fmt.Println("A", m)
		case 3: // 実行する箇所を持たない
		case 4:
			fmt.Println("B", m)
		case 5:
			fallthrough  // 次の case にフォールスルーする
		case 6:
			fmt.Println("C", m)
		case 7:
			fmt.Println("D", m)
			fallthrough
		case 8:
			fmt.Println("E", m)
		}
	}
}
main.go

実行結果は次のようになります。

go run main.go
A 0
A 1
A 2
B 4
C 5
C 6
D 7
E 7
E 8

コードの内容を説明します。

10行目では case ラベルに複数の値を指定しています。

		case 0, 1, 2: // 値を複数指定
			fmt.Println("A", m)

この場合、変数 m が値 0, 1, 2 のいずれかの時に A という文字が出力されます。

次に case 3: では処理する内容が記述されていません。

		case 3: // 実行する箇所を持たない
		case 4:
			fmt.Println("B", m)

この場合は m3 という値の場合は何もしません。

一方、 case 5: では fallthrough キーワードを使い、次の case にフォールスルーしています。

		case 5:
			fallthrough  // 次の case にフォールスルーする
		case 6:
			fmt.Println("C", m)

従ってこの場合 m の値が 5 の場合と 6 の場合に C という文字が出力されます。

次の箇所のように、何か処理をしてからフォールスルーすることもできます。

		case 7:
			fmt.Println("D", m)
			fallthrough
		case 8:
			fmt.Println("E", m)

Go の switch 内スコープの変数

次の例では rand.Intn(3) 関数で 0 から 2 までの値を取る乱数を生成して、それを変数 m に格納。 switch 文では m の値で条件分岐しています。

package main

import (
	"fmt"
	"math/rand"
	"time"
)

func main() {
	rand.Seed(time.Now().UnixNano()) // 乱数のシード
	m := rand.Intn(3) // 0 から 2 までの乱数を生成
	switch m {
	case 0:
		fmt.Println("Zero")
	case 1:
		fmt.Println("One")
	case 2:
		fmt.Println("Two")
	}
}

ここでは m の値が 0, 1, 2 のときにそれぞれ、 ZeroOneTwo という文字を出力しています。

このとき、変数 m を switch の外で使わないのであれば、次のように switch キーワードの後に変数の宣言をすることが可能です。

switch m := rand.Intn(3); m { // ここで宣言
case 0:
	fmt.Println("Zero")
case 1:
	fmt.Println("One")
case 2:
	fmt.Println("Two")
}

変数の宣言文をセミコロン ; で終了して、その次に switch による評価対象となる変数を記載します。

Go の switch で case に条件式を使う

Go の switch では case に続いて、条件式を記述できます。

m := rand.Intn(10)
switch {
case m < 5:
	fmt.Println("Less than 5")
case m == 5:
	fmt.Println("Equal to 5")
case m > 5:
	fmt.Println("Greater than 5")
}

この場合、switch 文にて変数を指定しません。 switch キーワードの後空白のあとすぐに { となっています。

switch 文で宣言する変数がある場合には、 宣言文の終わりにセミコロンを記述し、そのあとは空白のままにします。

switch m := rand.Intn(10); {
case m < 5:
	fmt.Println("Less than 5")
case m == 5:
	fmt.Println("Equal to 5")
case m > 5:
	fmt.Println("Greater than 5")
}

Go の switch での暗黙的なブロック

Go の switch 文で、case に続く箇所は暗黙的なブロックとして認識されます。

このため、次のように case 毎のスコープとして変数を宣言できます。

package main

import (
	"fmt"
	"math/rand"
)

func main() {
	i := 100 // switch の外で宣言
	fmt.Println("A", i)
	switch m := rand.Intn(10); {
	case m < 5:
		i := 10 // case 毎に宣言可
		fmt.Println("[1]", i)
	case m == 5:
		i := 20 // case 毎に宣言可
		fmt.Println("[2]", i)
	case m > 5:
		i := 30 // case 毎に宣言可
		fmt.Println("[3]", i)
	}
	fmt.Println("B", i)
}
main.go

実行例は次の通りです。

go run main.go
A 100
[1] 10
B 100

9行目で変数 i を宣言し、値 100 で初期化。 さらに switch 文内部で 13, 16, 19 行目でそれぞれ別の変数 i を宣言しています。これらは全て別の変数として扱われます。

ここまでお読みいただき、誠にありがとうございます。SNS 等でこの記事をシェアしていただけますと、大変励みになります。どうぞよろしくお願いします。

© 2024 Go 言語入門