「 switch文ってなに…? 」
「 条件分岐ってどう使えばいいの…? 」
プログラムにおいて、処理を条件によって分岐させることはよくあります。
Swift言語にもそういった処理の分岐方法の1つとして、switch文が用意されています。
本記事では、「switch文」の使い方と活用方法をはじめに、同じく条件分岐処理が可能な「if文」との使い分けについても触れていきたいと思います。
[ 本記事はこんな人におすすめ ]
・Swiftでアプリ開発をしている
・条件分岐の使い方にまだ慣れていない
・if文とswitch文の使い分け方を知りたい
switch文ってなに?
switch文は、if文と同じく、特定の条件によってコード処理を分岐するために用いる制御構文の一つです。
特に、複数の条件を”網羅的”に評価して処理を分岐したい時に活用できます。
【基本構文】
switch 値 {
case 条件1:
// 値が条件1と一致する場合に実行されるコード
case 条件2:
// 値が条件2と一致する場合に実行されるコード
default:
// 上記のいずれの条件にも一致しない場合に実行されるコード
}
判定する値をセットすることで、switch文は定義された条件(case)に値がマッチしているかどうかを上から順番に評価していきます。
条件にマッチした時点で、その条件下に記述されたコードを実行し、処理を終了します。
switch文の使い方(基本)
値の判定と評価
switch文は「ある何らかの値」を判定評価したり、その結果によって処理を分岐するために活用できます。
String
型、Int
型、Double
型、enum
型など、さまざまなデータ型の値を評価することが可能です。
【swtich文の使用例】
// String型の条件判定の例
let day = "土曜日"
switch day {
case "日曜日":
print("燃えるゴミの日")
case "水曜日":
print("不燃物の日")
case "土曜日":
print("資源のゴミの日") // ⭕️ 条件が成立するのでこのコードが実行される
default:
print("ゴミの日ではありません")
}
// 上記の実行結果:
// 資源のゴミの日
// Int型の条件判定の例
for index in 1...6 {
switch index {
case 1...3:
print("\(index):1〜3の場合に実行")
case 4 :
print("\(index):4の場合に実行")
default:
print("\(index):1〜4以外")
}
}
// 上記の実行結果:
// 1:1〜3の場合に実行
// 2:1〜3の場合に実行
// 3:1〜3の場合に実行
// 4:4の場合に実行
// 5:1〜4以外
// 6:1〜4以外
Viewの出し分け
switch文はViewの中で記述することが可能です。
これにより、例えばSwiftUIのVStackやHStackなどのビューコンテナにswitch文を置いて、画面のレイアウトを切り替えるような実装ができます。
以下に、Viewの出し分けをswitch文で実装したコード例を挙げます。
じゃんけんを表すサンプル画像のImageビュー(グー、チョキ、パー)を3種類用意し、switch文で@Stateプロパティ(状態変数)の値を評価して、値によって画像を切り替えています。
【実装コード】
/// Int値によってじゃんけんを切り替える実装
struct ContentView: View {
// switch文の判定に用いるプロパティ
@State var jankenNumber = 1
var body: some View {
VStack {
// switch文で値を評価し、じゃんけん画像を切り替える
switch jankenNumber {
case 1:
Image("gu")
.resizable()
.frame(width: 200, height: 200)
case 2:
Image("choki")
.resizable()
.frame(width: 200, height: 200)
case 3:
Image("pa")
.resizable()
.frame(width: 200, height: 200)
default:
Text("じゃんけんを選択してください")
}
/// プロパティの値を更新するボタン群
HStack {
Button("グーを出す") { jankenNumber = 1 }
Button("チョキを出す") { jankenNumber = 2 }
Button("パーを出す") { jankenNumber = 3 }
}
} // VStack
} // body
} // View
このように@Stateプロパティ(状態変数)とswitch文を組み合わせることで、プロパティの値の状態によってViewを出し分けるような実装を実現できます。
switch文の使い方(応用)
条件マッチ後、直下の処理を実行(fallthrough)
通常、switch文は条件を上から順に評価し、条件にマッチした時点で判定処理を終了します。
条件マッチ後、意図的に直下の処理も実行させたい場合は、指定の条件文のクロージャに「fallthrough(フォールスルー)」を記述します。
以下のコードは、1〜6の値を順番に判定していく処理コードです。値が「4」のケース処理にfallthroughを指定しています。
実行結果を見ると、値が「4」の時、直下のdefault:の処理が続けて実行されていることがわかります。
for index in 1...6 {
switch index {
case 1...3:
print("\(index): 値は1〜3です")
case 4:
print("\(index): 値は4です")
fallthrough // 直下の処理も行う指定
default:
print("\(index): 値は4〜6です") // ひとつ前の条件で fallthrough が指定されているため、4の場合にも実行
}
}
// 実行結果:
// 1: 値は1〜3です
// 2: 値は1〜3です
// 3: 値は1〜3です
// 4: 値は4です ⬅ 4の場合、直下のdefault処理が続けて実行される
// 4: 値は4〜6です ⬅ 4の時に実行されたdefault処理の結果
// 5: 値は4〜6です
// 6: 値は4〜6です
✅ fallthroughは直下の処理を"条件の真偽に関係なく"実行する
留意点として、fallthroughが実行された場合、条件の真偽に関係なく直下の処理が実行されます。
以下のコードは、1〜4の値を順番に評価し、「偶数」か「奇数」かを判定する処理コードです。
実行結果を見ると、偶数の条件がマッチしたとき、直下の奇数判定処理が、条件の真偽に関係なく実行されていることがわかります。
for number in 1...4 {
switch number % 2 {
case 0:
print("\(number)は偶数です")
fallthrough // ⬅︎ 直下の処理を実行
case 1:
print("\(number)は奇数です")
fallthrough // ⬅︎ 直下の処理を実行
default:
print("\(number)の判定を終了")
}
}
// 実行結果:
// 1は奇数です
// 1の判定を終了
// 2は偶数です
// 2は奇数です // ⬅︎
// 2の判定を終了
// 3は奇数です
// 3の判定を終了
// 4は偶数です
// 4は奇数です // ⬅︎
// 4の判定を終了
複数の条件をまとめて指定
条件を「,(コンマ)」で繋げることで、複数の条件をまとめて指定することができます。
for number in 1...8 {
switch number {
case 0, 2, 4:
print("\(number)は「0」か「2」か「4」です")
case 1, 3, 5:
print("\(number)は「1」か「3」か「5」です")
default:
print("\(number)は「0〜5」ではありません")
}
}
列挙型(enum)を使った条件分岐
switch文は列挙型(enum)との相性がとても良く、よく利用される手法です。
以下のコードは、曜日をenumのケースとして定義し、switch文の条件判定に利用しているコード例です。
// 曜日をenum型で定義
enum Week {
case monday, tuesday, wednesday, thursday, friday, saturday, sunday
}
// 上記で作成したenum「Week」型の値
let day = Week.monday
switch day {
case .monday:
print("筋トレをする日")
case .tuesday:
print("英語を勉強する日")
case .wednesday:
print("テニスをする日")
case .thursday:
print("ヨガをする日")
case .friday:
print("ランニングをする日")
default:
print("アプリを作る日")
}
enumに定義したケースをswitch判定に用いることで、
・「””」で囲む文字列の記述で発生するタイプミスのリスクをケアできる
・ケース記述時にXcodeの予測変換を使用できる
など、より安全なコードで条件分岐処理を行うことができます。
✅ enum + switch文 におけるdefaultの省略について
switch文に列挙型(enum)を用いている時、全てのenumのケースを条件として網羅していれば、defaultを省略することができます。
// 方角をenum型で定義
enum Direction {
case north, south, east, west
}
let direction = Direction.north
// 全てのケースを網羅している時、defaultを省略できる
switch direction {
case .north:
print("方角は北です")
case .south:
print("方角は南です")
case .east:
print("方角は東です")
case .west:
print("方角は西です")
}
このようにdefaultを省略した場合、全てのケースを網羅できていないと、Xcodeがケース記述漏れを検知してエラーを出します。
この機能が非常に強力で、例えば後からenumのケースを新規追加した場合に、意図せずswitch文の条件の追加を書き忘れるといったリスクを防ぐことができます。
【ケース漏れによるエラーの様子】
上記のエラーは、
・不足しているenumケースをswitch文の条件に追加する
・defaultをswitch文の条件に追加する
といった方法を取ることで解消されます。
defaultを追加した際は、全てのenumケースを網羅しているという保証が無くなるため、用途によって使い分けましょう。
if文とswitch文の使い分け
switch文の使用が適しているパターン
if文とswitch文どちらも同じく、条件によって処理を分岐するという機能を持ちます。
では、switch文の使用が適しているのはどのような場合なのか、見ていきましょう。
1. 評価する条件が多い場合
一般的に、値の判定条件が3つ以上存在する場合、if文よりもswitch文での記述の方が可読性が高く、読みやすいコードとされています。
enumを用いて、if文とswitch文それぞれのコードを見比べてみます。
enumは方角を表しており、評価に用いるケースは合計で4つ(北、南、東、西)です。
// 方角をenum型で定義
enum Direction {
case north, south, east, west
}
// 条件判定に用いるenum型プロパティ
let direction = Direction.north
// switch文
switch direction {
case .north:
print("方角は北です")
case .south:
print("方角は南です")
case .east:
print("方角は東です")
case .west:
print("方角は東です")
}
// if文
if direction == .north {
print("方角は北です")
} else if direction == .south {
print("方角は南です")
} else if direction == .east {
print("方角は東です")
} else if direction == .west {
print("方角は西です")
}
上記のコードはどちらも同じ実行結果が得られますが、switch文の方が
・1つの値を複数の条件で評価しているということ
・一体どんな値を評価に使っているのか
といったことが読み取りやすいですね。
このように評価する条件が多い場合、switch文の使用が適していると言えます。
2. 網羅的に条件分岐を行う必要がある場合
条件分岐をプログラムに用いる際に、発生しうる全てのケースに対しての処理を網羅する必要がある場合、switch文の使用が適しています。
前述と同じenumを使って、if文とswitch文それぞれのコードを見比べてみます。
今回注目する点として、評価する条件を「北」「南」の2つの場合のみとしており、「東」「西」の場合の処理は記述していません。
この場合、if文は問題なくビルドが通りますが、switch文ではエラーとなります。
switch文では「どの条件にも当てはまらない時」の記述(default)が必ず必要であるというのがエラーの理由です。
// 方角をenum型で定義
enum Direction {
case north, south, east, west
}
// 条件判定に用いるプロパティ
let direction = Direction.north
// switch文
// 全てのケースに対しての処理を網羅する必要がある
switch direction {
case .north:
print("方角は北です")
case .south:
print("方角は南です")
// defaultの記述が無いためエラー❌
}
// if文
// 全てのケースに対しての処理を網羅する必要はない
if direction == .north {
print("方角は北です")
} else if direction == .south {
print("方角は南です")
}
仮に「どの条件にも当てはまらない時」の記述を追加した場合、それぞれ以下のようなコードになります。
if文は“書かなくてもいい”のに対し、switch文は“書く必要がある”のがポイントです。
// switch文
// defaultによって「条件に当てはまらない場合」を表現する
switch direction {
case .north:
print("方角は北です")
case .south:
print("方角は南です")
default: // ⬅︎
print("方角は北と南ではありません")
}
// if文
// else節によって「条件に当てはまらない場合」を表現する
if direction == .north {
print("方角は北です")
} else if direction == .south {
print("方角は南です")
} else { // ⬅︎
print("方角は北と南ではありません")
}
このようなswitch文の特徴によって、発生しうる全てのケースに対しての処理が網羅されていることを保証することができます。
ここまで挙げた要件をまとめると、3つ以上の評価条件が存在し、全てのケースに対して処理を実行する必要がある場合に、switch文の使用が適していると言えます。
まとめ
以上、Swift言語におけるswitch文についてでした!
最後に、ここまで紹介したswitch文の要点をまとめておきます。
・複数の条件によって処理を分岐させるために使用する
・多様なデータ型を評価することができる(String, Int, Double, enum, etc…)
・3つ以上の条件かつ、全てのケースに対して処理を行いたい場合に適している
switch文はプログラミングの中でも非常に多用する条件式ですので、積極的に活用して使いこなせるようになりましょう!
今回比較として登場したif文については、以下の記事で詳しく解説していますので、よければこちらの記事も参考にしていただければと思います。
本記事が参考になれば幸いです👍
\ SHARE /
アプリ開発が学べる勉強会を開催中!
CodeCandyではアプリ開発を学ぶための勉強会を定期開催しています。
学習する習慣を身につけたい、他の参加者と作業したい、アプリ開発の基本をマスターしたい、という方のために無料で学べる勉強会です。
グループにメンバー登録して頂くと、イベント開催時にメールで通知されます。
徹底した基礎学習からマスターするiPhoneアプリ開発集中オンライン講座開講!
本書「iPhoneアプリ開発集中講座」を執筆している現役エンジニア講師陣が直接に指導!
基礎、課題実習で実践力を鍛えて、オリジナルアプリ公開までチャレンジ!
充実した転職支援もあるので、エンジニアへ転職したい人にもおすすめです!
まずは、現役エンジニアに相談できる無料相談をご利用ください。