Swift: Swiftの条件分岐:if-elseとswitch文の完全ガイド
条件分岐は、信号機が交通状況に応じて信号を変えるように、プログラムが異なる状況に異なる反応をすることを可能にします。このレッスンではSwiftのすべての条件制御機構(if-else、switchなど)を学びます。
1. 学習目標
- if / else if / elseを使った分岐ロジック
- switchを使った複数値マッチングとパターンマッチング
- 範囲演算子
...と..<を使った範囲条件の簡略化 - switchのcaseフォールスルーのためのfallthroughの使用
- where句を使った条件への追加制約の付与
2. 実話:バックエンド開発者のケース
(1) 課題:多層ロールベース権限がコードをスパゲッティに
BobはSaaS企業でユーザー権限システムを構築しています。システムには5つのユーザーロール(admin / editor / viewer / guest / banned)があり、それぞれ20以上のAPIエンドポイントに対して異なるアクセスレベルを持っています。Bobは最初に15層のネストされたif-elseを使用しました:
SWIFT
if role == "admin" {
if action == "delete" {
// allow
} else if action == "edit" {
// allow
}
} else if role == "editor" {
// 700 lines of repeated code...
}
コードは急速に700行以上に膨れ上がりました。新しいロールを追加するには5つの異なる場所を修正する必要がありました。Bobはif-elseの順序の誤りによって引き起こされたセキュリティ脆弱性の修正に丸一週間費やしました。
(2) 解決策:switch
Bobはswitch文を使って権限システムをリファクタリングしました:
SWIFT
let role = "editor"
switch role {
case "admin":
print("Full access granted")
case "editor":
print("Read and write access")
case "viewer", "guest":
print("Read-only access")
case "banned":
print("Access denied")
default:
print("Unknown role")
}
(3) 結果:コードが80%縮小、ロジックが明確に
| 観点 | 15層のif-else | switchリファクタリング後 |
|---|---|---|
| コード行数 | 700+ | 150 |
| 新しいロール追加時間 | 30分 | 3分 |
| ロジックエラー | 月3件 | 月0件 |
| 可読性スコア | 3/10 | 9/10 |
3. if/else条件文
if/elseはSwiftの最も基本的な条件制御構造です。Bool値に基づいてどのコードブロックを実行するかを決定します。
graph TB
A[条件] -->|true| B[ifブロック]
A -->|false| C[else if / elseブロック]
B --> D[続行]
C --> D
| 構文 | 説明 | 例 |
|---|---|---|
| if 条件 { } | 条件がtrueの場合に実行 | if score >= 60 { } |
| if ... else { } | 条件がfalseの場合にelseを実行 | if ... else { } |
| if ... else if ... else { } | 複数の条件を順にチェック | if ... else if ... else { } |
(1) 基本的なifとelse
SWIFT
let temperature = 30
if temperature > 25 {
print("It's hot outside")
} else {
print("It's cool outside")
}
(2) else ifによる複数条件
SWIFT
let score = 85
if score >= 90 {
print("Grade: A")
} else if score >= 80 {
print("Grade: B")
} else if score >= 70 {
print("Grade: C")
} else if score >= 60 {
print("Grade: D")
} else {
print("Grade: F")
}
▶ サンプル: ログイン状態チェック
SWIFT
// ============================================
// Display different messages based on login status
// ============================================
let isLoggedIn = true
let hasProfile = false
if isLoggedIn {
print("Welcome back!")
if hasProfile {
print("Your profile is complete")
} else {
print("Please complete your profile")
}
} else {
print("Please log in first")
}
出力:
TEXT 📖 参照専用Welcome back! Please complete your profile
4. switch 複数分岐マッチング
switchはif-elseよりも強力な複数分岐マッチングツールです。Swiftのswitchはbreakが不要で、マッチ後に自動的に実行を終了します。
graph TB
A[値] --> B[case 1]
A --> C[case 2]
A --> D[case 3]
A --> E[default]
B --> F[実行して終了]
C --> F
D --> F
E --> F
| 特徴 | Swiftのswitch | C / Javaのswitch |
|---|---|---|
| 暗黙のbreak | 自動(break不要) | breakを書く必要あり |
| 範囲マッチン�� | ... と ..< をサポート |
非サポート |
| 複合マッチング | カンマ区切りの値 | fallthroughに依存 |
| 網羅性 | すべての可能性をカバー必須 | 強制されない |
| デフォルト分岐 | defaultを使用 | defaultを使用 |
(1) 基本的なswitch構文
SWIFT
let fruit = "apple"
switch fruit {
case "apple":
print("It's an apple")
case "banana":
print("It's a banana")
case "orange":
print("It's an orange")
default:
print("Unknown fruit")
}
(2) 範囲マッチングと複合マッチング
SWIFT
let age = 25
switch age {
case 0..<13:
print("Child")
case 13..<20:
print("Teenager")
case 20..<65:
print("Adult")
case 65...:
print("Senior")
default:
print("Invalid age")
}
▶ サンプル: HTTPステータスコードの処理
SWIFT
// ============================================
// Handle HTTP response status codes with switch
// ============================================
let statusCode = 404
switch statusCode {
case 100..<200:
print("Informational")
case 200..<300:
print("Success")
case 300..<400:
print("Redirection")
case 400..<500:
print("Client error")
if statusCode == 404 {
print("Resource not found")
}
case 500..<600:
print("Server error")
default:
print("Unknown status code")
}
出力:
TEXT 📖 参照専用Client error Resource not found
5. 高度な制御:fallthrough、where、三項演算子
Swiftは条件ロジックをより柔軟にする追加ツールを提供します。
| ツール | 目的 | 例 |
|---|---|---|
| fallthrough | switchで次のcaseにフォールスルー | case "a": fallthrough |
| where | 条件に追加のフィルタリングを付与 | case let x where x > 10: |
| 三項 ? : | 簡潔な二者択一 | let max = a > b ? a : b |
(1) fallthrough
SWIFT
let number = 2
switch number {
case 1:
print("One")
case 2:
print("Two")
fallthrough
case 3:
print("Three or fell through from two")
default:
print("Other")
}
(2) where条件フィルタリング
SWIFT
let point = (x: 3, y: 4)
switch point {
case let (x, y) where x == y:
print("On the diagonal")
case let (x, y) where x > y:
print("X is larger")
case let (x, y) where x < y:
print("Y is larger")
default:
print("On an axis")
}
(3) 三項条件演算子
SWIFT
let isMember = true
let discount = isMember ? 0.2 : 0.0
print("Discount: \(discount * 100)%")
▶ サンプル: 注文割引計算機
SWIFT
// ============================================
// Combine if/switch/ternary to calculate order discounts
// ============================================
let orderTotal = 250.0
let customerTier = "gold"
// Ternary operator: base discount
let baseDiscount = orderTotal > 100 ? 0.05 : 0.0
// switch: membership tier discount
let tierDiscount: Double
switch customerTier {
case "platinum":
tierDiscount = 0.20
case "gold":
tierDiscount = 0.15
case "silver":
tierDiscount = 0.10
default:
tierDiscount = 0.0
}
// if: cap the combined discount
let totalDiscount = baseDiscount + tierDiscount
let finalDiscount = totalDiscount > 0.3 ? 0.3 : totalDiscount
let finalPrice = orderTotal * (1 - finalDiscount)
print("Order total: $\(orderTotal)")
print("Tier: \(customerTier)")
print("Discount: \(Int(finalDiscount * 100))%")
print("Final price: $\(finalPrice)")
出力:
TEXT 📖 参照専用Order total: $250.0 Tier: gold Discount: 20% Final price: $200.0
6. 完全な例:ユーザー権限管理システム
SWIFT
// ============================================
// User permission management system
// Integrates if/switch/where/ternary operators
// ============================================
import Foundation
enum UserRole {
case admin, editor, viewer, guest, banned
}
enum ActionResult {
case granted, denied(String)
}
func checkPermission(role: UserRole, action: String, isOwner: Bool) -> ActionResult {
switch role {
case .banned:
return .denied("Account is banned")
case .admin:
return .granted
case .editor:
if action == "delete" && !isOwner {
return .denied("Only owners can delete")
}
return .granted
case .viewer:
switch (action, isOwner) {
case (_, false):
return .denied("Viewers cannot modify content")
case ("read", true):
return .granted
default:
return .denied("Unknown action")
}
case .guest:
return action == "read" ? .granted : .denied("Guests can only read")
}
}
let testCases = [
(UserRole.admin, "delete", false),
(UserRole.editor, "delete", true),
(UserRole.editor, "delete", false),
(UserRole.viewer, "read", true),
(UserRole.viewer, "write", false),
(UserRole.guest, "read", false),
(UserRole.banned, "read", false)
]
for (role, action, isOwner) in testCases {
let result = checkPermission(role: role, action: action, isOwner: isOwner)
switch result {
case .granted:
print("[GRANTED] \(role) can \(action)")
case .denied(let reason):
print("[DENIED] \(role) cannot \(action) -- \(reason)")
}
}
出力:
TEXT 📖 参照専用[GRANTED] admin can delete [GRANTED] editor can delete [DENIED] editor cannot delete -- Only owners can delete [GRANTED] viewer can read [DENIED] viewer cannot write -- Viewers cannot modify content [GRANTED] guest can read [DENIED] banned cannot read -- Account is banned
❓ よくある質問
Q Swiftのswitchにbreakが不要なのはなぜですか?
A Swiftのswitchはcaseにマッチした後自動的に終了し、次のcaseにフォールスルーしません。意図的にフォールスルーするには明示的にfallthroughを書く必要があります。
Q ifとswitchの使い分けは?
A 2〜3分岐の場合は
ifを使用します。3分岐以上、または範囲/パターンマッチングが必要な場合はswitchを使用します。switchはすべての可能性を網羅的に処理することを強制するため、ifよりも安全です。Q
...と..<の違いは?A
a...bはaとbの両方を含みます(閉範囲)。a..<bはaを含みますがbを含みません(半開範囲)。例えば、1...3は1,2,3を含み、1..<3は1,2を含みます。Q 三項演算子はコードの可読性を損ないませんか?
A 単純な二者択一(代入など)では、三項演算子は簡潔で明確です。三項演算子をネストしたり、ロジックが複雑になったりする場合は、代わりに
ifを使用してください——長い1行は読みにくくなります。Q default分岐を省略できますか?
A いいえ。Swiftのswitchは網羅的でなければなりません。すべてのケースを網羅している場合(例:列挙型のすべてのケース)、defaultを省略できます。
📖 まとめ
- if/elseは最も基本的な条件制御で、2〜3分岐に最適
- switchは3分岐以上に最適で、範囲マッチング、複合マッチング、値バインディングをサポート
- switchのfallthroughで次のcaseにフォールスルー可能、順次マッチングのシナリオに有用
- where句でswitchのcaseやforループに追加のフィルタリング条件を付与
- 三項演算子? :は簡潔な二者択一の代入に最適
- Swiftのswitchは網羅的な処理を要求し、コードの安全性を高める
📝 練習問題
- 初級: if/elseを使って体温分類器を作成:体温 < 36.0 は「低め」、36.0...37.5 は「正常」、> 37.5 は「発熱」と出力してください。
- 中級: 初級の練習問題をswitchを使ってリファクタリングし、体温 < 35.0 で「危険な低体温」と出力するケースも追加してください。範囲マッチング構文を使用してください。
- 上級: 支払い手数料計算機を作成してください。手数料ルール:クレジットカード 2.5%(≥$100の場合 2.5% - 0.5%)、デビットカード 1.0%(上限$5)、PayPal 3.0% + $0.30。switch + whereで実装してください。