オプショナルバインディング
型の存在の有無を冗長な書き方にしないためのif-let構文。if letで指定したOptional型の変数がnilでなければ、構文の中でアンラップ済みの変数を使えるようにする。
ダウンキャストもif letで対応できる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
let oa = Optional("a") if let a = oa { print("\(a)") } else { print("nil") } let ob = Optional("b") if let a = oa, let b = ob { print("\(a),\(b)") } else { print("nil") } let any : Any = 1 if let iany = any as? Int { print("\(iany)") } |
guard,guard-let
ある関数のスコープ内で、guardで指定した条件が満たされることを保証する。
関数の先頭で引数に対してguardを定義することで引数の前提条件を書いたりする。
if-letのguard版(guard-let)もある。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
func someFunc() { let value = 1 guard value >= 0 else { return } // ここまで来たならvalueが0以上であることを保証する print("0以上です。") } func someFunc2() { let any : Any = 1 guard let iany = any as? Int else { return } print("\(iany)") } |
nil可能な引数を取る加算関数をif,guard両方で書くと以下。
guardで書いた方が見通しがよくなる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
func add(_optionalA:Int?, _optionalB:Int?) -> Int? { let a: Int let b: Int if let unwrappedA = _optionalA { a = unwrappedA } else { return nil } if let unwrappedB = _optionalB { b = unwrappedB } else { return nil } return a + b } func add2(_optionalA:Int?, _optionalB:Int?) -> Int? { guard let a = _optionalA else { return nil } guard let b = _optionalB else { return nil } return a + b } |
for-in,for-case
for-inで要素の全てにアクセスする。for-caseで条件を満たす要素にアクセスする。
foreachで回す先頭で条件でスキップする奴はfor-caseで書ける。
1 2 3 4 5 6 7 8 |
let dict:Dictionary<String,Int> = ["a":1,"b":2] for (key,value) in dict { print("\(key):\(value)") } let ary:Array<Int> = [1,2,3,4] for case 2...3 in ary { print("2以上3以下") } |
fallthrough
switch文の各caseの終わりでfallthroughを書いたときに初めて後ろのcaseが実行される。
fallthroughを書かないと条件にマッチしたcaseした実行されない。
なので、switch-caseの各caseの末尾にbreakを書く必要はない。
1 2 3 4 5 6 7 8 9 10 |
let a = 1 switch a { case 1: print("case1") fallthrough case 2: print("case2") default: print("other") } |
遅延実行
関数の評価時ではなく、関数のスコープから抜けたときに実行する文を記述する。
以下、関数評価時にはgは0だが、関数がスコープから抜けたときにdeferが評価されgが1になる。
1 2 3 4 5 6 7 8 9 10 |
var g = 0 func someFunc2() -> Int { defer { g += 1 } print("\(g)") return g } someFunc2() print("\(g)") |