The Swift Programming Language - Closures（クロージャー）をまとめる


[The Swift Programming Language をまとめるトップ](http://qiita.com/kiyotaman/items/052f82e9f93590b79c64)

## Closures（クロージャー）
C言語やOjbCのブロックや他lambdas（ラムダ）に類似している
キャプチャの所は丁寧にやった

### The Sort Function（ソート関数）
Swiftには配列をソートする **sort** 関数がある
**sort** が完了したら、以前の配列のサイズと型が同じ新しい配列を生成する
**sort** 関数の引数は二つ

* 第一引数は配列
* 第二引数はクロージャーで引数を二つ取り戻り値は *Bool* 

> sort(Array, (String, String) -> Bool)


以下の、文字列配列を降順にソートしてみる

```swift
let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]

func backwards(s1: String, s2: String) -> Bool {
    return s1 > s2
}
var 降順 = sort(names, backwards)
// 降順 の中身 ["Ewa", "Daniella", "Chris", "Barry", "Alex"]
```

### Closure Expression Syntax（クロージャー書き方）
一般的な書き方

```swift
{ (引数,,,) -> 戻り値型 in
     ステートメント
}
```

例えば

```swift
降順 = sort(names, { (s1: String, s2: String) -> Bool in
    return s1 > s2
    })
```

### Inferring Type From Context（型の推論）
Swift は引数の型など推論できる場合がある
型や（->）も省くことができる
読み手に分かりやすくしたい時は、明示したほうが良い場合もある

```swift
降順 = sort(names, { s1, s2 in return s1 > s2 } )
```

### Shorthand Argument Names（簡易引数名）
引数を参照する為の *$0, $1, $2* 等を自動に提供する
もっと手軽に短く書ける

```swift
降順 = sort(names, { $0 > $1 } )
```

### Operator Functions（演算子関数）
更に短く書ける

```swift
降順 = sort(names, >)
```


### Trailing Closures（後置記法）
関数の最後の引数は（）の外に出す事ができる
{} ブロック内が長い場合など便利

```swift
func someFunctionThatTakesAClosure(closure: () -> ()) { // function body goes here }
 
// これが後置記法で無い場合
someFunctionThatTakesAClosure({ // closure's body goes here })
 
// これが後置記法の場合
someFunctionThatTakesAClosure() { // 後述 closure's body goes here }
```

後置記法で **sort** 関数は以下の様にも書く事ができる

```swift
reversed = sort(names) { $0 > $1 }
```

Trailing Clouser はクロージャー内のコードが長いときに便利
配列は **map** メソッドをもっていて、Tailing クロージャーに対応
サンプルソースのみ紹介

```swift
let digitNames = [
    0: "Zero", 1: "One", 2: "Two",   3: "Three", 4: "Four",
    5: "Five", 6: "Six", 7: "Seven", 8: "Eight", 9: "Nine"
]
let numbers = [16, 58, 510]
let strings = numbers.map {
    (var number) -> String in
    var output = ""
    while number > 0 {
        output = digitNames[number % 10]! + output
        number /= 10
    }
    return output
}
// strings は String[] として推論される
// 値の中身 ["OneSix", "FiveEight", "FiveOneZero"]
```

### Capturing Values（キャプチャ値）
クロージャーはそれが定義された周辺の定数や変数を捉えて操作（キャプチャ）することができる
クロージャーの文中でそれらの定数や変数の値を参照したり修正したりすることができる
その定数や変数が元のスコープ（つまりそのクロージャー文中外）で定義されて、それが既に破棄されていても文中内で値を参照したり操作できる
キャプチャ値によって、変数や定数をコピーしたり参照操作したりすることができる

一番シンプルクロージャーは関数の文中にあるネストされた関数
ネストされた関数はそのネストされた関数内の範囲で、ネストしている関数の引数や他あらゆる定数や変数を捉えて操作することができる

*incrementor* というネストされた関数をもつ *makeIncrementor* という関数を使った以下の例をみてみる
ネストされた *incrementor* 関数が周辺にある二つの値 *runningTotal* と *amount* を捉えて処理している
その処理後、 *incrementor* は *makeIncrementer* が毎回呼ばれるたびに *runnintTotal* の数値を加算するクロージャーとして返される

```swift
func makeIncrementor(forIncrement amount: Int) -> () -> Int {
    var runningTotal = 0
    func incrementor() -> Int {
        runningTotal += amount
        return runningTotal
    }
    return incrementor
}
```

*makeIncrementor* は *() -> Int* 型を戻り値とする
つまり、 ***値を戻り値とするということではなく、関数を戻り値とする*** ということ
この関数が呼ばれる毎に、引数が指定されていない Int を戻り値とする関数を返す
関数がどんな関数を返すかは、戻り値としての関数型を見る必要がある

*makeIncrementor* 関数では *runningTotal* 変数を定義し現在の running total を保持し *incrementor* によって返される
この *runnintTotal* は 0 で初期化されている

*makeIncrementor* 関数は *forIncrement* という外側で引数を渡すときに分かりやすくするために付けられた名前が指定されているInt型の外部引数をもっていて、関数内では *amount* としてローカルの名前を使って操作できる
この引数は、戻り値となる *incrementor* 関数が呼ばれるたびにどれくらい加算するか保持している

*makeIncrementor* は *incrementor* というネストされた関数を文中で定義し、それが実際の加算処理を行う
この関数は単純に *runningTotal* 変数に *amount* を加えて、結果として返す処理をするだけ

*incrementor* 関数だけ見た場合、少し不自然

```swift
func incrementor() -> Int {
    runningTotal += amount
    return runningTotal
}
```

*incrementor* だけみると関数は引数がなく、{} 文中に *runningTotal* や *amount* として定義されたものはなく外側で定義されたものということが分かる

外側の関数の *amount* 引数は修正ができないので、 *incrementor* はその値を参照し新たな *amount* に複写保存する
そして、この *amount* は *incrementor* 関数内でのみ有効となる

*incrementor* が呼ばれる毎に *runningTotal* 変数が更新される
*incrementor* 内の *runningTotal* は外側で定義された *runningTotal* を参照しているだけで初期化された複写ではない
また、 *makeIncrementor* が呼ばれる時に *runningTotal* が破棄されない様に参照し、次に *incrementor* 関数が呼ばれる時に永続して利用できるよにしている

**実際の処理**

```swift
let incrementByTen = makeIncrementor(forIncrement: 10)
```

*incrementor* 関数型の関数 *incrementByTen* を引数 10 で定義し実行してみる

```swift
incrementByTen()
// 戻り値 10
incrementByTen()
// 戻り値 20
incrementByTen()
// 戻り値 30
```

別の *incementor* をつくってみる

```swift
let incrementBySeven = makeIncrementor(forIncrement: 7)
incrementBySeven()
// 戻り値 7
incrementByTen()
// 戻り値 40
```

> **NOTE**
> クロージャーをクラス属性（property）にアサインしたり、そのクラスのインスタンスやメンバー変数に参照されたクロージャーの場合、強参照で参照される
> [Strong Reference Cycles for Closures を参照すべし](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/AutomaticReferenceCounting.html#//apple_ref/doc/uid/TP40014097-CH20-XID_61)

### Closures Are Reference Types（クロージャー参照型）
上記の例の *incrementBySeven* や *incrementByTen* は *定数* である
これらのクロージャーは参照型で、定数が参照してるクロージャーは *runningTotal* 変数を永続的に保持操作できる

関数やクロージャーを定数や変数に定義するたびに、実際は関数やクロージャーを参照している定数や変数を定義していることになる
*incrementByTen* はただの定数で、クロージャーそのものではない

以下は２つの異なる定数か変数を定義した時、それぞれ同じクロージャーを参照していることがわかる

```swift
let alsoIncrementByTen = incrementByTen
alsoIncrementByTen()
// 戻り値 50
// incrementByTen() と同じクロージャーを参照している
```