基本的な使い方
下が基本的な使い方です。
下のケースではdefaultは必須になります。
breakは不要です。
let value = { return 1 }()
switch value {
case 0: print(0)
case 1: print(1) // ここに来る
case 2: print(2)
default: print(-1)
}
結果が自明な場合の挙動
結果が自明な場合は不要な要素の所で警告が出ます。
その場合はdefaultを省略できます。
let value = 1
switch value {
case 0: print(0)
case 1: print(1) // ここに来る
case 2: print(2)
}
Enumとの組み合わせ
enumで全要素を網羅すればdefaultを省略できます。
enum MyEnum {
case A, B, C
}
let value: MyEnum = { return .A }()
switch value {
case .A: print("A")
case .B: print("B")
case .C: print("C")
}
全要素を書かない場合はdefaultが必須です。
let value: MyEnum = { return .A }()
switch value {
case .A: print("A")
default: print("default")
}
処理を記述しない場合
処理を1行も書かない場合はbreakを書く必要があります。
let value = { return 1 }()
switch value {
case 1: break
default: break
}
次の条件を実行する
fallthroughを使うと一つ下のcaseを実行できます。
条件に合っていなくても実行されます。
混乱を招きそうなので使う事はほとんどないです。。
let value = { return 1 }()
switch value {
case 1:
print(1)
fallthrough
case 2:
print(2) // → fallthroughがあるのでここに来る
default: break
}
ワイルドカードを使う
_ は default を使った時のような動きをします。
let value = { return 1 }()
switch value {
case 1: print(1)
case _: print("_") // 1以外の時は常にここに来る
}
ワイルドカードで引っかかった変数の値を取る
let xxx
とした場合もワイルドカードと同じ動きになります。
letの代わりにvarも使えます。
let value = { return 10 }()
switch value {
case 1: print(1)
case let other: print(other) // → 10
}
whereを使った分岐
case文にはwhereを使う事もできます。
let value = { return "a" }()
switch value {
case "" where Int(value) != nil: print("")
case let other where Int(other) != nil: print(other)
default: break
}
Tupleと使う
switch文にはTupleも使えます。
let value = { return (1, 1) }()
switch value {
case (1, 1): print(1)
case (2, 2): print(2)
default: break
}
UITableViewのIndexPathによる分岐の時に使う事が多いです。
let indexPath = NSIndexPath(forRow: 1, inSection: 2)
switch (indexPath.section, indexPath.row) {
case (0, 0): print(0, 0)
case (0, 1): print(0, 1)
case (1, 0): print(1, 0)
case (1, 1): print(1, 1)
case (1, 2): print(1, 2)
default: break
}
Tupleとワイルドカードを併用する
片方の値だけワイルドカードを使う事もできます。
let indexPath = NSIndexPath(forRow: 1, inSection: 2)
switch (indexPath.section, indexPath.row) {
case (0, 0): print(0, 0)
case (0, _): print(0, -1) // sectionが0でrowが0以外の時に来る
case (let section, _): print(section, -1) // 上の条件に当てはまらない時に来る
}
NSDateへの適用
NSDateに対しても使う事ができます。
let value = NSDate(timeIntervalSince1970: 1)
switch value {
case NSDate(timeIntervalSince1970: 0): print(0)
case NSDate(timeIntervalSince1970: 1): print(1)
default: break
}
Rangeへの適用
Range(1...2)でも使えます。
let value = 1
switch value {
case 1...2: print(1, 2)
case 3...4: print(3, 4)
default: break
}
独自クラスとRangeやIntを比較できるようにする
独自クラスであるAppVersionにcase 1
やcase 2...3
を使いたい場合は~=
演算子を定義すれば良いです。
func ~= (int: Int, version: AppVersion) -> Bool {
return version.value == int
}
func ~= (range: Range<Int>, version: AppVersion) -> Bool {
return range ~= version.value
}
class AppVersion {
let value: Int
init(value: Int) { self.value = value }
}
let version = AppVersion(value: 1)
switch version {
case 1: print(1)
case 2...3: print(2...3)
default: break
}