switch
このページでは豊富な例を用いてGolangのswitch文の使い方を学ぶことができます。
switch文は与えた式を元に条件分岐を実現するGolangの制御構文の1つです。
switchキーワードに式を指定し、その式が「switch文内に記述したcaseキーワードに指定した値」と一致する場合に該当のcaseブロック(case節)の処理が実行されます。
defaultキーワードを使用すると、どのcaseにも当てはまらない場合の処理を記述することができます。
注意事項として、一部のプログラミング言語でのswitch文と異なり、break文を使用しなくとも該当のcase節・default節の処理のみが実行されます。
// 記述例
switch 式 {
case 値1:
// 式 == 値1となるときに実行される処理
case 値2:
// 式 == 値2となるときに実行される処理
default:
// どのcaseにも当てはまらない場合に実行される処理
}
TL;DR
基本
// 「switchに指定した値」と「caseに指定した値」が一致するブロックの処理が実行される
string1 := "Go"
switch string1 {
case "Golang":
fmt.Println("case1")
case "Go":
fmt.Println("case2")
default:
fmt.Println("default")
}
==> case2
// どのcaseにも一致しないとdefaultのブロックが実行される
int2 := 100
switch int2 {
case 0:
case 1:
fmt.Println("case2")
default:
fmt.Println("default")
}
==> default
// どのcaseにも一致せずdefaultが無い場合は何も実行されない
int3 := 100
switch int3 {
case 0:
fmt.Println("case1")
case 1:
fmt.Println("case2")
}
==> 出力なし
// caseに複数の値を指定することもできる
switch 100 {
case 0, 1, 2:
fmt.Println("case1")
case 100, 200:
fmt.Println("case2")
}
==> case2
// 「switchに指定した型」と「caseに指定した型」に互換性がないとエラー
float4 := 3.14
switch float4 {
case 1.4:
fmt.Println("case1")
case 100: // 100はfloatとしての100.0と扱われる
fmt.Println("case2")
case "Go":
fmt.Println("case3")
}
==> cannot use "Go" (type untyped string) as type float64
簡易文の記述
// switchには簡易文(simple statement)を指定することもできる
switch int1 := 1; int1 {
case 1:
fmt.Println("case1")
case 2:
fmt.Println("case2")
default:
fmt.Println("default")
}
==> case1
caseに条件式を指定
// switchに何も指定しないとbool値を判定するようになる
int1 := 10
switch {
case int1 < 5:
fmt.Println("case1")
case int1 == 5:
fmt.Println("case2")
case int1 > 5:
fmt.Println("case3")
default:
fmt.Println("default")
}
==> case3
// 上記のswitch文は以下の記述と同じ
switch true {
case int1 < 5:
fmt.Println("case1")
case int1 == 5:
fmt.Println("case2")
case int1 > 5:
fmt.Println("case3")
default:
fmt.Println("default")
}
==> case3
fallthroughの指定
// fallthroughキーワードを使用すると次のブロックの処理も実行される
string1 := "A"
switch string1 {
case "A":
fmt.Println("case1")
fallthrough
case "B":
fmt.Println("case2")
case "C":
fmt.Println("case3")
default:
fmt.Println("default")
}
==> case1
==> case2
// fallthroughキーワードを複数用いた場合
int2 := 1
switch int2 {
case 0:
fmt.Println("case1")
case 1:
fmt.Println("case2")
fallthrough
case 2:
fmt.Println("case3")
fallthrough
default:
fmt.Println("default")
}
==> case2
==> case3
==> default
型switch文
// 値ではなく型を場合分けに使用できる
var value1 interface{} = 0
switch value1.(type) {
case int:
fmt.Println("case1")
case bool:
fmt.Println("case2")
case float32:
fmt.Println("case3")
default:
fmt.Println("default")
}
==> case1
// switchに指定する型はinterface{}型でなければならない
value2 := "Go"
switch value2.(type) {
case string:
fmt.Println("case1")
}
==> (エラー)cannot type switch on non-interface value value2 (type string)
// caseのブロックで変数を使う
var value3 interface{} = "Golang"
switch val := value3.(type) {
case int:
fmt.Println("case1", val*val)
case string:
fmt.Println("case2", val+"!!!")
}
==> case2 Golang!!!
// caseに複数の型を指定した場合、valはinterface{}型としてあつかわれるのでエラー
var value4 interface{} = "Golang"
switch val := value4.(type) {
case int, int8:
fmt.Println("case1", val)
case string, bool:
fmt.Println("case2", val + "!!!")
}
==> (エラー)invalid operation: val + "!!!" (mismatched types interface {} and string)
解説
// 記述例
switch 式 {
case 値1:
// 式 == 値1となるときに実行される処理
case 値2:
// 式 == 値2となるときに実行される処理
default:
// どのcaseにも当てはまらない場合に実行される処理
}
基本
switch文は「switchキーワードに指定した式(値)」と、「caseキーワードに指定した値」が一致する場合にcase節(caseブロック)の処理が実行されます。
caseは複数指定することもできます。
記述したどのcaseにも当てはまらない場合、switch文の処理は実行されません。
defaultキーワードを使用すると「どのcaseにも当てはまらない場合に実行する処理」を記述することができます。
また、caseには,
(カンマ)区切りで複数の値を指定することもできます。
注意事項が2つあります。
1つ目は、「caseに指定することができる値」は「switchに指定した式(値)の型と互換性のあるもの」しか指定できません。
2つ目は、Go言語のswitch文ではbreak文を指定せずとも一致したcase節の処理のみが実行されることです。
他の一部のプログラミング言語では、switch文を使用して条件分岐を行う際にcase節の最後にbreak
文を指定しないと次のcase節、
default節の処理も続けて実行されてしまうといった仕様があります。
Go言語では異なりますので注意してください。
int1 := 1
switch int1 {
case 0:
fmt.Println("case1")
case 1:
fmt.Println("case2")
default:
fmt.Println("default")
}
==> case2
// どのcaseの値にも当てはまらずdefaultがある場合
switch 1 {
case 0:
fmt.Println("case1")
default:
fmt.Println("default")
}
==> default
// どのcaseの値にも当てはまらずdefaultがない場合
switch 1 {
case 0:
fmt.Println("case1")
case 2:
fmt.Println("case2")
}
==> 出力なし
// caseに複数の値を指定
string3 := "go"
switch string3 {
case "string", "int":
fmt.Println("case1")
case "golang", "go":
fmt.Println("case2")
}
==> case2
// switchに指定した値と型の互換性が無い場合
int4 := 100
switch int4 {
case 6.0: // 6.0は6として扱われるのでOK
fmt.Println("case1")
case "golang":
fmt.Println("case2")
}
==> cannot use "golang" (type untyped string) as type int
簡易文の記述
switch文のswitchキーワードの後ろには、式だけでなく簡易文(simple statement)を記述することもできます。
簡易文を記述したい場合、式の前に;
(セミコロン)区切りで簡易文を記述します。
この簡易文で変数を宣言・代入することで、switch文内でのみ有効な変数を定義することができます。(スコープがswitch文内の変数)
これはswitch文以外の処理部分へ影響を与えずに済むので、switch文内でのみ使用したい値は簡易文で定義することが推奨されます。
switch value := "golang"; value {
case "go":
fmt.Println("case1")
case "golang":
fmt.Println("case2")
default:
fmt.Println("default")
}
==> case2
caseに条件式を指定
switchキーワードの後ろに式を記述しないこともできます。
この場合switch true
と記述された場合と同様になり、caseキーワードには条件式などbool値(真偽値)を返すものを指定できるようになります。
switch {
case "golang" == "golang":
fmt.Println("case1")
case "go" == "golang":
fmt.Println("case2")
default:
fmt.Println("default")
}
==> case1
// 上記のswitch文は以下と同じ
switch true {
case "golang" == "golang":
fmt.Println("case1")
case "go" == "golang":
fmt.Println("case2")
default:
fmt.Println("default")
}
==> case1
fallthroughの指定
Go言語では該当するcase節・default節の処理のみが実行されます。
fallthrough
文を使用することで他のプログラミング言語にあるような、
「breakを記述しないと、次のcase文の処理も実行する挙動」を実現することができます。
int1 := 0
switch int1 {
case 0:
fmt.Println("case1")
fallthrough
case 1:
fmt.Println("case2")
case 2:
fmt.Println("case3")
default:
fmt.Println("default")
}
==> case1
==> case2
// fallthroughキーワードを複数使用する場合
string2 := "B"
switch string2 {
case "A":
fmt.Println("case1")
case "B":
fmt.Println("case2")
fallthrough
case "C":
fmt.Println("case3")
fallthrough
default:
fmt.Println("default")
}
==> case2
==> case3
==> default
型switch文
通常switch文は指定された式の値をもとにして条件分岐を実行します。
しかし、指定する式を型アサーション(type assertion)に似た形式で指定すると、型をもとにした条件分岐を実装できます。
これは「型switch文(Type Switch)」とも呼ばれます。
対象となる値はinterface{}
型である必要があり、型アサーションと異なり()
丸括弧内にはtype
というキーワードを指定します。
また、通常のswitch文と同様にcaseに複数の型を指定することもできますが、 複数の型を使用しているcase節内では「該当の変数はinterface{}型として扱われる」ことに注意してください。
var value1 interface{} = "ABC"
switch value1.(type) {
case int:
fmt.Println("case1")
case uint:
fmt.Println("case2")
case string:
fmt.Println("case3")
default:
fmt.Println("default")
}
==> case3
// switchで指定する変数はinterface{}型である必要がある
value2 := 100
switch value2.(type) {
case string:
fmt.Println("case1")
}
==> (エラー)cannot type switch on non-interface value value2 (type int)
// switch文内で変数を使用する
var value3 interface{} = 10
switch val := value3.(type) {
case int:
fmt.Println("case1", val*val)
default:
fmt.Println("default", val)
}
==> case1 100
// caseに複数の型を指定した場合はswitch文内でinterface{}型として扱われる
var value4 interface{} = 10
switch val := value4.(type) {
case int, int8, int64:
fmt.Println("case1", val*val)
default:
fmt.Println("default", val)
}
==> (エラー)invalid operation: val * val (operator * not defined on interface)
1次情報
Switch - Control structures - Effective Go - The Go Programming Language
Switch statements - The Go Programming Language Specification - The Go Programming Language