closure expressionと呼ばれる構文です。
https://docs.swift.org/swift-book/LanguageGuide/Closures.html
要するに「引数を与えて何かを計算し結果を返してくれるようなオブジェクト」のことです。これは関数そのものといえ、Swiftは関数そのものもデータとして変数へ代入したり別の関数の引数として渡したり関数から返したりといったことができます。(Swiftに限らず多くの言語でも同様のことができ、大変強力なのでこれを知っておくとプログラミングの幅が広がると思います。)
大雑把なclosureのあれこれ:
関数的なものをデータとして扱えるということは「それに型がある」ということになりますが、例えば「整数を2つ与えて整数を返すようなクロージャオブジェクト」を表す型は
(Int, Int) -> Int
と表現します。またこのクロージャーオブジェクトを引数にとる関数を定義できて
swift
1// 整数配列をop演算によって集約する
2func reduce(_ array: [Int], _ initial: Int, op: (Int, Int) -> Int) -> Int {
3 var accumulator = initial
4 for e in array {
5 accumulator = op(accumulator, e)
6 }
7 return accumulator
8}
9
10let a = [1, 3, 4]
11print(reduce(a, 0) { (a, b) in a + b }) // => 8 (加算による集約:累加)
12print(reduce(a, 1) { (a, b) in a * b }) // => 12 (乗算による集約:累積)
のように、クロージャーを用いることで「大変単純な定義であるにも関わらず多彩な計算を行える汎用性を持つ」ものにできます。
なおSwiftのclosureは色々な省略構文が工夫されており、例えば上の例を省略せずに書くと
{ (a: Int, b: Int) -> Int in return a + b }
となりますが、a, bの型やclosureの結果の型はreduceの引数が(Int, Int) -> Intであることから型推論により確定できるため省略できます。また単一の式をreturnする場合はreturnも省略できます。またclosureを最終の引数にした場合、
swift
1let result = reduce(a, 0, { (a, b) in a + b })
2
3// と書く代わりに
4
5let result = reduce(a, 0) { (a, b) in
6 a + b
7}
8
9// とも書ける
ということで、複数行にわたり複雑な計算を行うようなクロージャーであっても括弧の入れ子が深くなりすぎず、スッキリした見栄えでコードを表現できます。
このあたりはclosure expressionに関する文法をよく学んでおくと、いろいろな書き方を目にしてもビックリせずにすむと思います。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/05/12 15:31