オプショナルバインディング</h3
Optional型の存在の有無を冗長な書き方にしないためのif-let構文。
if letで指定したOptional型の変数がnilでなければ、構文の中でアンラップ済みの変数を使えるようにする。
ダウンキャストもif letで対応できる。
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)もある。
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で書いた方が見通しがよくなる。
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で書ける。
let dict:Dictionary = [\"a\":1,\"b\":2]
for (key,value) in dict {
print(\"(key):(value)\")
}
let ary:Array = [1,2,3,4]
for case 2...3 in ary {
print(\"2以上3以下\")
}
fallthrough
switch文の各caseの終わりでfallthroughを書いたときに初めて後ろのcaseが実行される。
fallthroughを書かないと条件にマッチしたcaseした実行されない。
なので、switch-caseの各caseの末尾にbreakを書く必要はない。
let a = 1
switch a {
case 1:
print(\"case1\")
fallthrough
case 2:
print(\"case2\")
default:
print(\"other\")
}
遅延実行
関数の評価時ではなく、関数のスコープから抜けたときに実行する文を記述する。
以下、関数評価時にはgは0だが、関数がスコープから抜けたときにdeferが評価されgが1になる。
var g = 0
func someFunc2() -> Int {
defer {
g += 1
}
print(\"(g)\")
return g
}
someFunc2()
print(\"(g)\")