はじめに
前回の実験では、if-else 分岐文の使い方について学びました。この実験では、switch-case 分岐文について学習します。switch 文は、if-else 文と比較して、複数の条件を扱うシナリオにより適しています。
学習ポイント:
- switch-case 文
- default キーワード
- fallthrough キーワード
基本構文
switch 分岐文の構文は、条件判定を伴うという点で if 分岐文と似ています。基本的な構文は以下の通りです。
switch condition {
case val1:
// コードブロック
case val2:
// コードブロック
...
default:
// コードブロック
}
条件(condition)には、あらゆる型の式を使用できます。条件が特定の case 文の値と一致すると、対応するコードブロックが実行され、プログラムは現在の switch 分岐から抜けます。
case 文に指定する値は、条件式の型と同じである必要があります。
プログラムは case 文を上から下へと評価し、最初に一致した case 文を実行します。実行が完了すると、switch ブロックを終了します。
default 文は else 文に似ています。どの case 文も条件に一致しない場合に、default 文が実行されます。
天気予報の例を見てみましょう。switch.go という名前の新しいファイルを作成し、以下のコードを記述します。
cd ~/project
touch switch.go
package main
import (
"fmt"
)
func main() {
// 今日の天気
weather := "rainy"
switch weather {
case "snow":
fmt.Println("Remember to wear a scarf today.🧣")
case "rainy":
fmt.Println("Remember to bring an umbrella today.🌂")
default:
fmt.Println("Today is sunny.☀")
}
}
コードを実行します。
go run switch.go
出力結果は以下の通りです。
Remember to bring an umbrella today.🌂
この天気予報プログラムは、天候の状態に応じて異なる結果を出力します。まず、今日の天気を "rainy"(雨)に設定しました。その下の switch-case 分岐では、3 つの異なる条件を設定しています。雪が降ればマフラーを巻くように、雨が降れば傘を持つように促し、それ以外の場合は晴れの日として扱います。
分岐内での複数値の指定
case 文には、以下のように複数の値を指定することもできます。
switch condition {
case val1, val2:
// コードブロック
...
}
天気予報プログラムを次のように更新しました。
package main
import (
"fmt"
)
func main() {
// 今日の天気
weather := "snow"
switch weather {
case "snow", "stormy":
fmt.Println("Remember to wear a scarf today.🧣")
case "haze", "sandstorm":
fmt.Println("Remember to wear a mask today.😷")
case "rainy":
fmt.Println("Remember to bring an umbrella today.🌂")
default:
fmt.Println("Today is sunny.☀")
}
}
go run switch.go
実行後の出力は以下の通りです。
Remember to wear a scarf today.🧣
いくつかの気象条件を追加しました。霞(haze)や砂嵐(sandstorm)の場合は、マスクを着用するように促します。
条件変数のない switch 文
switch 文における条件変数は、省略可能なパラメータです。条件変数を省略した場合、switch 文は if-else 文と同様の動作をします。
前のセクションで作成した「今日の曜日を出力する」プログラムを、条件変数のない switch 文を使って書き換えてみましょう。
package main
import (
"fmt"
"time"
)
func main() {
today := time.Now().Weekday()
switch {
case today == time.Monday:
fmt.Println("Today is Monday.")
case today == time.Tuesday:
fmt.Println("Today is Tuesday.")
case today == time.Wednesday:
fmt.Println("Today is Wednesday.")
case today == time.Thursday:
fmt.Println("Today is Thursday.")
case today == time.Friday:
fmt.Println("Today is Friday.")
case today == time.Saturday:
fmt.Println("Today is Saturday.")
default:
fmt.Println("Today is Sunday.")
}
}
go run switch.go
実行後の出力は以下の通りです(実行した曜日によって異なります)。
Today is Monday.
このプログラムでは、switch 文から条件変数が取り除かれています。プログラムが実行されると、各 case 分岐の条件が満たされているかどうかをチェックします。条件が満たされると、その分岐のコードが実行され、最後に switch ブロックを抜けます。
fallthrough 文
前述の通り、通常プログラムは case 分岐を実行した後、現在の switch 分岐を終了します。
もし、ある case 分岐を実行した後に、続けて次の分岐ステートメントも実行したい場合は、fallthrough 文を使用します。
fallthrough 文を使用する際の仕様は以下の通りです。
- デフォルトでは、
switch文がcase 10に一致して実行された後、後続の分岐は実行されません。fallthrough文を記述すると、後続のcase分岐を強制的に実行します。 fallthroughは直後のcase文にのみ影響し、そのcaseの条件チェックは行われません。fallthroughはswitchの最後の分岐では使用できません。
具体的な例を見てみましょう。
package main
import (
"fmt"
)
func main() {
n := 10
switch n {
case 10:
fmt.Println(10)
fallthrough
case 3:
fmt.Println(3)
}
}
go run switch.go
実行後の出力は以下の通りです。
10
3
この switch 分岐では、case 10 に一致したため 10 を出力し、その後 fallthrough によって次の case ステートメントの内容である 3 も出力されました。
switch 文における初期化文
Go 言語では、if 分岐文だけでなく、switch 分岐文にも初期化文(initialization statement)を記述できます。条件変数の前に初期化文を書き、セミコロンで区切ります。
チャレンジ
それでは、前のセクションのプログラムを書き換えて、初期化文を switch 文の中に移動させてみましょう。
switch2.go という名前の新しいファイルを作成します。以下のコードを switch2.go ファイルに記述し、前のセクションのプログラムを修正して初期化文を switch 文の中に組み込んでください。
cd ~/project
touch switch2.go
前のセクションのコードは以下の通りです。
package main
import (
"fmt"
)
func main() {
n := 10
switch n {
case 10:
fmt.Println(1)
fallthrough
case 3:
fmt.Println(3)
}
}
要件:
switch2.goファイルは~/projectディレクトリに配置すること。
ヒント: 修正にあたっては、if-else の実験における初期化プログラムのセクションを参考にしてください。
まとめ
この実験では、switch 分岐文について解説しました。主なポイントは以下の通りです。
case文が一致して実行されると、通常は現在のswitchブロックを終了します。fallthroughを使用すると、条件に関わらず次のcase文を続けて実行できます。switchにも初期化文を記述でき、条件式とはセミコロンで区切ります。



