省略記法
Swift のクロージャの基本的な書き方はこう:
let sorted = sort(anArray, { (s1: String, s2: String) -> Bool in
return s1 < s2
})
型推論が効くので、仮引数の型とカッコ、返り値の型は省略できる:
let sorted = sort(anArray, { s1, s2 in
return s1 < s2
})
クロージャ本体が式ひとつだけからなる場合、 return
も省略できる:
let sorted = sort(anArray, { s1, s2 in s1 < s2 })
プレースホルダを使えばここまで短くなる:
let sorted = sort(anArray, { $0 < $1 })
さらに、 <
演算子を operator function として渡すこともできる:
let sorted = sort(anArray, <)
後置記法
関数の最後の引数に渡すクロージャは、関数呼び出しの後ろに置くことができる(Ruby と同じ):
let doubled = map([1, 2, 3], { $0 * 2 })
// ↓
let doubled = map([1, 2, 3]) { $0 * 2 }
@autoclosure
@autoclosure
属性を持つ引数に渡される式は、評価されずにクロージャとしてキャプチャされる:
func doTwice(f: @autoclosure () -> Void) {
f()
f()
}
doTwice(print("hello")) // => hellohello
面白いが使いどころが思いつかない。明示的にクロージャを書けばいいと思うんだが。→短絡評価する演算子を定義するとき使えるとのこと
キャプチャリスト
クロージャが外部の変数をどうキャプチャするか指定できる。 Objective-C で面倒だった self の循環参照回避が簡単になる:
// self がクロージャを強参照し、クロージャが self を強参照して循環参照に陥る
self.aProperty = {
self.doSomething()
}
// unowned self としてキャプチャすると、クロージャは self を所有しない
self.aProperty = {
[unowned self] in
self.doSomething()
}