##クロージャの文法
{ ( parameters ) -> return type in
statements
}
一般的に以下のような記述があったとします。
let array = [“Taro”, “Hanako”, “Jiro”, “Aki”, “Jun"]
func later(_ s1: String, _ s2: String) -> Bool {
return s1 > s2
}
var sortArray = array.sorted(by: later)
sorted(by:)
メソッドは配列の内容と同じ型の2つの引数を取り、Bool値を返すことで、1つ目の値が2つ目の値の前後に並べ替えるかを示します。
今回の例では、配列の内容がString値のため、(String, String) -> Bool
型のクロージャを必要とします。
クロージャの文法通りに正しく記述するとなると以下のようになります。
クロージャ式構文の引数は、デフォルト値を持つことができません。
reversedNames = names.sorted(by: { (s1: String, s2: String) -> Bool in
return s1 > s2
})
このインラインクロージャの引数と返り値の型の宣言は、先ほどの later(_: _:)関数の宣言と同じになっています。そのためどちらも (s1: String, s2: String) -> Bool
と書かれています。
クロージャの本文はin
から開始されます。このin
はクロージャの引数と返り値の型宣言が終了したことを明示します。
そのため、1行にして記述することもできます。
クロージャの本文が複数行になる際は、;
で区切ることで1行に記述することも可能ですが、swiftらしい記述ではありません。
reversedNames = names.sorted(by: { (s1: String, s2: String) -> Bool in return s1 > s2 })
##型推論
{}内はsorted(by:)
メソッドの引数として渡されるため、Swiftでは引数と返り値の型推論が可能です。今回の場合では、(String, String) -> Boolの型でないといけないため、クロージャ内で型の定義を省略できます。全ての型が推論出来るため、矢印->
と引数を囲う括弧もまた省略されます。
reversedNames = names.sorted(by: { s1, s2 in return s1 > s2 })
##暗黙的な戻り値
単一式クロージャでは暗黙的にその結果を返すことが出来ます。そのため、宣言からreturn
を省略することができます。
reversedNames = names.sorted(by: { s1, s2 in s1 > s2 })
この省略は必ずしも適用出来るわけではないですが、今回では、sorted(by:)
メソッドの引数にはBool値がクロージャにて返されなければ行けません。クロージャ本体ではBool値を返す単一式(s1 > s2)が含まれているため、return
を省略することができます。
##引数名の省略
Swiftのインラインクロージャでは、簡略化された引数名を提供しています。クロージャの引数の値を $0,$1,$2…
で参照することができます。
クロージャの式内でこれらの短縮形の引数を使用する際に、クロージャの引数のリストもまた省略することが出来ます。省略された名前と型は、関数の型から推測されます。そして、クロージャの本文のみで構成されているため、in
も省略できます。
reversedNames = names.sorted(by: { $0 > $1 })
$0
が第一引数、$1
が第二引数を参照します。
###参考
Apple公式ドキュメント
https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Closures.html#//apple_ref/doc/uid/TP40014097-CH11-ID94