クロージャ


クロージャ はあなたのコードで渡され使用できる機能性の自己完結型のブロックです。Swift におけるクロージャは C と Objective-C のブロックと似ており、他のプログラミング言語でのラムダに似ています。


クロージャは、それらが定義されている文脈から任意の定数および変数への参照をキャプチャし、保存できます。これは、それらの定数や変数の クロージング として知られています。Swift は、あなたのキャプチャしたメモリ管理のすべてを処理します。


注意: 「キャプチャ」の概念に精通していなくても、心配しないでください。これは、値のキャプチャ 以下で詳しく説明します。


グローバルと入れ子になった関数は、関数 で紹介したように、実際にはクロージャの特殊なケースです。クロージャは3つの形式のいずれかを取ります:


Swift のクロージャ式は、一般的なシナリオの中に簡単な、すっきりした構文を促す、最適化された、きれいな、明確なスタイルを持っています。これらの最適化は以下のものを含みます:


クロージャ式


入れ子になったた関数は、入れ子になった関数 で紹介したように、より大きな関数の一部として、コードの自己完結型のブロックを命名し、定義する便利な手段です。しかし、それは完全な宣言と名前なしに関数のような形式の短いバージョンを記述するのに便利な場合があります。それらの1つ以上の引数として関数を取る関数やメソッドで作業する場合に特にそれは当てはまります。


クロージャ式 は、簡単に一つの行でクロージャを書く方法で、焦点を当てる構文です。クロージャ式は、明瞭さまたは意向を見失うことなく省略形でクロージャを記述するためのいくつかの構文の最適化を提供します。クロージャ式の例を以下に挙げ、単一の sorted(by:) メソッドの例を磨き上げて、これらの最適化を説明し、より簡潔な方法でそれぞれが同じ機能を表現します。


ソートするメソッド


Swift の標準ライブラリは、あなたが提供するソート・クロージャの出力に基づいて、既知の型の値の配列を並べ替える sorted(by:) と呼ばれるメソッドを提供します。それがソート処理を完了すると、sorted(by:) メソッドは正しい順序でその要素を、古いものと同じ型とサイズの新しい配列を返します。元の配列は sorted(by:) メソッドによって変更されません。


クロージャ式の例を以下に挙げ、逆アルファベット順で String 値の配列を並べ替える sorted(by:) メソッドを使用します。ここで並べ替える最初の配列はこうです:


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



sorted(by:) メソッドは、配列の内容と同じ型の 2 つの引数を取るクロージャを受け付け、値が一旦ソートされると、最初の値が 2 番目の値の前か後かどうかを告げるために Bool 値を返します。ソートするクロージャは最初の値が 2 番目の値の になる場合は true を返し、それ以外の場合は false を返します。


以下の例では、String 値の配列を並べ替え、並べ替えするクロージャは (String, String) -> Bool 型の関数である必要があります。


ソートするクロージャを提供する1つの方法は、正しい型の正常な関数を書くことであり、sorted(by:) メソッドに引数として渡すことです:


  1. func backward(_ s1: String, _ s2: String) -> Bool {
  2.        return s1 > s2
  3. }
  4. var reversedNames = names.sorted(by: backward)
  5. // reversedNames is equal to ["Ewa", "Daniella", "Chris", "Barry", "Alex"]


最初の文字列(s1)が、第2の文字列(s2)よりも大きい場合、backward(_:_:) 関数は true を返し、s1 がソートされた配列の S2 の前に表示されるべきことを示します。文字列内の文字が、「より大きい」のは 「よりもアルファベットで後に現れる」事を意味します。これは、文字 "B" は文字 "A" 「より大きく」、文字列 "Tom" は文字列 "Tim" よりも大きいことを意味します。これは、逆順のアルファベットソートを与え、"Barry""Alex" の前に置かれる、などします。


しかし、これは本質的に一つの式の関数 (a > b)が何であるかを書くむしろ長ったらしい方法です。この例では、クロージャ式の構文を使用して、ソートするクロージャを一行で記述することが好ましいでしょう。



クロージャ式の構文


クロージャ式の構文は、以下の一般的な形式です:


クロージャ式構文の パラメータ は、in-out パラメータである事ができますが、デフォルト値を持つことができません。可変個引数パラメータに名前を付ければ可変個引数のパラメータを使用できます。タプルも、パラメータ型及び戻り値として使用できます。


以下の例では、以前の backward(_:_:) 関数のクロージャ式のバージョンを示しています。


  1. reversedNames = names.sorted(by: { (s1: String, s2: String) -> Bool in
  2.        return s1 > s2
  3. })


この一行に書いたクロージャのパラメータと戻り値の型の宣言が backward(_:_:) 関数からの宣言と全く同じであることに注意してください。両方の場合とも、それは (s1: String, s2: String) -> Bool として書かれます。しかし、一行に書いたクロージャ式では、パラメータと戻り値の型はそれらの外ではなく中括弧の に書かれています。


クロージャの本体の先頭は in キーワードによって始まります。このキーワードは、クロージャのパラメータと戻り値の型の定義が終了し、クロージャの本体が、始まろうとしていることを示しています。


クロージャの本体がとても短いので、それは一つの行に書くことができます:


reversedNames = names.sorted(by: { (s1: String, s2: String) -> Bool in return s1 > s2 } )



これは sorted(by:) メソッドへの全体的な呼び出しが同じままであることを示しています。括弧のペアは、まだメソッド全体の引数を包んでいます。しかし、その引数は今一行で書いたクロージャです。


文脈から型を推論


ソートするクロージャはメソッドに引数として渡されているので、Swift は、そのパラメータの型と、それが戻す値の型を推論できます。sorted(by:) メソッドは、文字列の配列上で呼び出されており、その引数は (String, String) -> Bool 型の関数でなければなりません。これは (String,String)Bool 型はクロージャ式の定義の一部として書く必要がないことを意味します。型のすべては推測できるので、戻り矢印(->)とパラメータの名前を囲む括弧も省略できます:


reversedNames = names.sorted(by: { s1, s2 in return s1 > s2 } )



一行のクロージャ式として関数やメソッドにクロージャを渡す時、パラメータの型と戻り値の型を推測することが常に可能です。その結果、クロージャが関数やメソッドの引数として使用される場合、完全な形で一行のクロージャを記述する必要はありません。


それにもかかわらず、お望みであれば、型を明示的にできるし、そしてコードの読者のために曖昧さを回避する場合にはそのように奨励されています。sorted(by:) メソッドの場合、クロージャの目的は、ソートが行われていることから明らかであり、クロージャが文字列の配列のソートを補助しているので、String 値を操作する可能性を読者は仮定することが安全です。



単一式クロージャからの暗黙的戻り値


単一式のクロージャは、前の例のバージョンのように、それらの宣言から return キーワードを省略して、その単一式の結果を暗黙的に返すことができます。


reversedName = 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 はクロージャの第一及び第二の String 引数を参照しています。



演算子メソッド


上記のクロージャ式を書く、さらに より短い 方法が実際にあります。Swift の String 型は String 型の二つのパラメータを持つメソッドとして大なり演算子(>) の文字列固有の実装を定義し、Bool 型の値を返します。これは正確に sorted(by:) メソッドに必要なメソッド型と一致します。したがって、単に、大なり演算子に渡すことができ、そして Swift は、あなたがその文字列固有の実装を使用したいことを推測します。


reversedNames = names.sorted(by, >)



演算子メソッドの詳細については、演算子メソッド を参照してください。


後続クロージャ


クロージャ式を関数に、関数の最後の引数として渡す時、クロージャ式が長い場合はクロージャ式は、その代わりにそれを 後続クロージャ として書くのが役立ちます。後続クロージャは、それが関数への引数だったとしても、関数呼び出しの括弧の後に書かれています。後続クロージャ構文を使用する時、関数呼び出しの一部としてクロージャの引数ラベルを書いてはいけません。


  1. func someFunctionThatTakesAClosure(closure: () -> Void) {
  2.        // function body goes here
  3. }
  4. // here's how you call this function without using a trailing closure:
  5. someFunctionThatTakesAClosure(closure: {
  6.        // closure's body goes here
  7. })
  8. // here's how you call this function with a trailing closure instead:
  9. someFunctionThatTakesAClosure() {
  10.        // trailing closure's body goes here
  11. }


上記の クロージャ式の構文 セクションから文字列ソートクロージャを引用すると、後続クロージャーとして sorted(by:) メソッドの括弧の外に書くことができます:


reversedNames = names.sorted() { $0 > $1 }



クロージャ式が関数またはメソッドの唯一の引数として提供される場合、関数を呼び出すときに、後続クロージャとしての式を提供する場合、関数やメソッドの名前の後の括弧 () のペアを記述する必要はありません。


reversedNames = names.sorted { $0 > $1 }


1行にインラインで書くことが不可能であるほどクロージャが十分に長い場合、後続クロージャは最も有用です。例として、Swift の Array 型には、その一つだけの引数としてクロージャ式を取る map(_:) メソッドがあります。クロージャは配列内の各項目に対して一度ずつ呼び出され、その項目に(おそらく他の型の)代替マッピングされた値を返します。マッピングされた性質と戻り値の型はクロージャが指定するのを任されています。


各配列要素に提供されたクロージャを任せた後、map(_:) メソッドは、元の配列内の対応する値と同じ順序で新しくマッピングされたすべての値を含む新しい配列を返します。


ここで、Int 値の配列を String 値の配列に変換するために、後続クロージャと map(_:) メソッドを使用する方法を示します。配列 [16、58、510] は、新しい配列 ["OneSix","FiveEight","FiveOneZero"] を作成するために使われます:


  1. let digitNames = [
  2.        0: "Zero", 1: "One", 2: "Two", 3: "Three", 4: "Four",
  3.        5: "Five", 6: "Six", 7: "Seven", 8: "Eight", 9: "Nine"
  4. ]
  5. let numbers = [16, 58, 510]


上記のコードは、整数の数字とその名前の英語バージョン間のマッピングの辞書を作成します。また、整数の配列を定義し、文字列に変換される準備ができます。


これで、後続クロージャとして配列の map(_:) メソッドにクロージャ式を渡して、String 値の配列を作成するために numbers の配列を使用できます:


  1. let strings = numbers.map { (number) -> String in
  2.        var number = number
  3.        var output = ""
  4.        repeat {
  5.                output = digitNames[number % 10]! + output
  6.                number /= 10
  7.        } while number > 0
  8.        return output
  9. }
  10. // strings is inferred to be of type [String]
  11. // its value is ["OneSix", "FiveEight", "FiveOneZero"]


map(_:) メソッドは、配列内の各項目ごとに一度ずつクロージャ式を呼び出します。マッピングされる配列内の値から型が推測できるので、クロージャの入力パラメータ、number の型を指定する必要はありません。


この例では、値は、クロージャ本体内で変更できるように、変数 number は、クロージャの number パラメータの値で初期化されます。(関数とクロージャへのパラメータは、常に定数です。)クロージャ式はまた、マッピングされた出力配列内に保存される型を示すために、String の戻り値の型も指定します。


クロージャ式は、それが呼び出されるたびに output と呼ばれる文字列をビルドします。これは、剰余演算子 (number % 10) を使用して number の最後の桁を計算し、digitNames 辞書内の適切な文字列を検索するためにこの数字を使います。クロージャは、ゼロより大きい任意の整数の文字列表現を作成するために使われます。


注意: 辞書のサブスクリプトはキーが存在しない場合、辞書の検索が失敗するかもしれないことを示すため optional の値を返すので、digitNames 辞書のサブスクリプトへの呼び出しは、感嘆符 (!) が続いています。上記の例では、number % 10 は、常に digitNames 辞書の有効なサブスクリプトキーである事を保証されており、感嘆符は、サブスクリプトの optional の戻り値に保存されている String 値を強制開封するために使用されます。


digitNames 辞書から得られた文字列は output前に 追加され、効果的に数字の逆順で文字列バージョンを構築します。(式 number % 10 の値は、16 では 658 では 8510 では 0 を与えます)


number 変数はその後 10 で割られます。整数であるため、割り算で切り捨てられ、そのため 161 になり、585 になり、51051 になります。


プロセスは number0 に等しくなるまで続き、その時点で output 文字列がクロージャによって返され、map(_:) メソッドにより出力配列に追加されます。


上記の例では後続クロージャ構文の使用が map(_:) メソッドの外側の括弧内のクロージャ全体を包む必要がなく、クロージャがサポートしているので、関数の直後にクロージャの機能をきちんとカプセル化しています。



値のキャプチャ


クロージャは、それが定義されている周囲の文脈から定数と変数を キャプチャ できます。クロージャは、その定数および変数を定義したオリジナルの範囲がもはや存在しない場合でも、その本体内からそれらの定数と変数の値を参照し、変更できます。


Swift では、値をキャプチャできるクロージャの最も簡単な形式は、別の関数の本体内で書かれた、入れ子になった関数です。入れ子になった関数は、その外側の関数の引数のいずれでもキャプチャでき、また、外側の関数内で定義された全ての定数と変数もキャプチャできます。


ここで入れ子になった incrementer と言う関数を含む makeIncrementer と言う関数の例を挙げましょう。入れ子になった incrementer() 関数は、その周囲の文脈から、二つの値、runningTotalamount をキャプチャします。これらの値をキャプチャした後、incrementeramount によって、それが呼び出されるたびに runningTotal を増分するクロージャとして makeIncrementer によって返されます。


  1. func makeIncrementer(forIncrement amount: Int) -> () -> Int {
  2.        var runningTotal = 0
  3.        func incrementer() -> Int {
  4.                runningTotal += amount
  5.                return runningTotal
  6.        }
  7.        return incrementer
  8. }


makeIncrementer の戻り値の型は () -> Int です。これは、単純な値ではなく、関数 を返すことを意味します。それが返す関数にはパラメータはなく、呼び出されるたびに Int 値を返します。関数が、他の関数を返す方法については、戻り値の型としての関数型 を参照してください。


makeIncrementer(forIncrement:) 関数は、返されるインクリメンタの現在実行中の合計を保存するために、runningTotals と呼ばれる整数の変数を定義しています。この変数は、0 の値で初期化されます。


makeIncrementer(forIncrement:) 関数は forIncrement の引数ラベルと、一つの Int パラメータを持ち、また amount のパラメーター名を持っています。このパラメータに渡された引数の値は、返されたインクリメンタの関数が呼び出されるたびに runningTotal が増分されるべき値を指定します。makeIncrementer 関数は実際の増分を行う、incrementer と言う入れ子になった関数を定義しています。この関数は、単純に amountrunningTotal に加算し、その結果を返します。


分離して考えると、入れ子になった incrementer() 関数は珍しく見えるかもしれません:


  1. func incrementer() -> Int {
  2.        runningTotal += amount
  3.        return runningTotal
  4. }


incrementer() 関数は、パラメータを全く持っていないし、まだそれはその関数本体内から runningTotalamount を参照しています。それは、その周囲の関数から runningTotalamount への 参照 をキャプチャする事によってこれを行い、関数本体内自体でそれらを使用します。参照によりキャプチャする事は runningTotalamount が、makeIncrementer への呼び出しが終了しても、消えない事を保証し、また runninTotalincrementer 関数が呼び出される次の回にも使用可能であることを保証します。


注意: 最適化の結果として、Swift はその値がクロージャにより変異されておらず、及びクロージャが作成された後値が変異されていない場合は、代わりに、値の コピー をキャプチャし、保存します。

Swift はまた、それらがもはや必要でない時に変数の処分に関係するすべてのメモリ管理を処理します。


ここで、アクションの makeIncrementer の例を示します。


let incrementByTen = makeIncrementer(forIncrement: 10)



この例では、その runningTotal 変数に、呼び出されるたびに 10 を追加するインクリメンタ関数を参照する incrementByTen という定数を設定します。関数を複数回呼び出すとこのアクションでの動作がわかるでしょう:


  1. incrementByTen()
  2. // returns a value of 10
  3. incrementByTen()
  4. // returns a value of 20
  5. incrementByTen()
  6. // returns a value of 30


インクリメンタを二回目に作成すると、それは新しい、独立した runningTotal 変数への独自の保存された参照を持つことになるでしょう。


  1. let incrementBySeven = makeIncrementer(forIncrement: 7)
  2. incrementBySeven()
  3. // returns a value of 7


オリジナルのインクリメンタ(incrementByTen)を呼ぶと、再び自身の runningTotal 変数を増分し続け、incrementBySeven によりキャプチャされた変数には影響しません:


  1. incrementByTen()
  2. // returns a value of 40


注意: もしクラス・インスタンスのプロパティにクロージャを割り当てて、クロージャがそのインスタンスまたはそのメンバーを参照することで、そのインスタンスをキャプチャする場合は、クロージャとインスタンス間で strong な循環参照を作成します。Swift は、これらの strong な循環参照を破壊するために キャプチャリスト を使用します。詳細については、クロージャの strong な循環参照 を参照してください。


クロージャは参照型


上記の例では、incrementBySevenincrementByTen は定数ですが、これらの定数が参照するクロージャはまだそれらがキャプチャした runningTotal 変数を増分することができます。これは、関数とクロージャが 参照型 のためです。


関数やクロージャを定数または変数に割り当てる時はいつでも、定数または変数が関数またはクロージャへの 参照 であることを実際に設定しています。上記の例では、それは incrementByTen がそれが定数である事に 参照 しているのはクロージャの選択で、クロージャ自体の内容ではありません。


2つの異なる定数や変数にクロージャを割り当てた場合、それらの定数または変数の両方とも同じクロージャを参照することをこれは意味します。


  1. let alsoIncrementByTen = incrementByTen
  2. alsoIncrementByTen()
  3. // returns a value of 50


クロージャのエスケープ


クロージャは、関数に引数として渡されますが、関数が戻した後に呼び出されるので関数を エスケープ すると言われます。そのパラメータの一つとしてクロージャを取る関数を宣言するときは、クロージャがエスケープするのを許可されていることを示すために、パラメータの型の前に @escaping と書けます。


クロージャがエスケープできる一つの方法は、関数の外で定義された変数に格納されている事です。例として、非同期操作を開始する、多くの関数が完了ハンドラとしてクロージャの引数を取ります。操作を開始した後関数は戻りますが、操作が完了するまでクロージャは呼び出されず、クロージャは後で呼ばれるように、エスケープする必要があります。例えば:


  1. var completionHandlers: [() -> Void] = []
  2. func someFunctionWithEscapingClosure(completionHandler: @escaping () -> Void) {
  3.         completionHandlers.append(completionHandler)
  4. }


someFunctionWithEscapingClosure(_:) 関数は、その引数としてクロージャをとり、関数の外で宣言されている配列にそれを追加します。@escaping で、この関数のパラメータをマークしなければ、コンパイルエラーになるでしょう。


@escaping でクロージャをマークすることは、明示的にクロージャ内の self を参照しなければならないことを意味します。たとえば、以下のコードでは、 someFunctionWithEscapingClosure(_:) に渡されたクロージャはエスケープするクロージャで、明示的に self を参照する必要があることを意味します。これとは対照的に、someFunctionWithNonescapingClosure(_:) に渡されたクロージャは、エスケープしないクロージャで、それは暗黙のうちに self を参照することができることを意味します。


  1. func someFunctionWithNonescapingClosure(closure: () -> Void) {
  2.         closure()
  3. }
  4. class SomeClass {
  5.         var x = 10
  6.         func doSomething() {
  7.                 someFunctionWithEscapingClosure { self.x = 100 }
  8.                 someFunctionWithNonescapingClosure { x = 200 }
  9.         }
  10. }
  11. let instance = SomeClass()
  12. instance.doSomething()
  13. print(instance.x)
  14. // Prints "200"
  15. completionHandlers.first?()
  16. print(instance.x)
  17. // Prints "100"


オートクロージャ


オートクロージャ は関数への引数として渡される式を包み込むために自動的に作成されるクロージャです。これは、引数を全く取りませんし、呼び出された時、その内側に包み込まれていた式の値を返します。この構文上の利便性は、明示的なクロージャの代わりに、正常な式を書くことにより、関数のパラメータの周りのカッコを省略できます。


オートクロージャを取る関数を 呼び出す のが一般的ですが、この種の関数を 実装する のは一般的ではありません。例えば、assert(condition:message:file:line:) 関数は、その conditionmesseage パラメータ用のオートクロージャを取りますが、その condition パラメータはデバッグビルドでのみ評価され、その message パラメータは、conditionfalse の場合にのみ評価されます。


オートクロージャは、あなたがクロージャを呼び出すまで、内部のコードは実行されませんので、評価を遅らせることができます。そのコードが評価されるときには、あなたがコントロールできますので、評価を遅らせることは、副作用を持っているか、計算コストが高いコードのために有用です。以下のコードは、クロージャが評価を遅延させる方法を示しています。


  1. var customersInLine = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]
  2. print(customersInLine.count)
  3. // Prints "5"
  4. let customerProvider = { customersInLine.remove(at: 0) }
  5. print(customersInLine.count)
  6. // Prints "5"
  7. print("Now serving \(customerProvider())!")
  8. // Prints "Now serving Chris!"
  9. print(customersInLine.count)
  10. // Prints "4"


customersInLine 配列の最初の要素がクロージャ内のコードによって除去されているにもかかわらず、クロージャが実際に呼び出されるまで、配列の要素は除去されません。クロージャが決して呼び出されない場合は、クロージャ内の式は評価されることは決してなく、それは配列の要素が決して除去されないことを意味します。customerProvider の型は String ではないですが、文字列を返す、パラメータのない () -> String の関数であることに注意してください。


関数の引数としてクロージャを渡すときは、遅延評価と同じ動作を得られます。


  1. // customersInLine is ["Alex", "Ewa", "Barry", "Daniella"]
  2. func serve(customer customerProvider: () -> String) {
  3.         print("Now serving \(customerProvider())!")
  4. }
  5. serve(customer: { customersInLine.remove(at: 0) } )
  6. // Prints "Now serving Alex!"


上記のリストの serve(customer:) 関数は、顧客(customer) の名前を返す、明示的なクロージャをとります。下記の serve(customer:) のバージョンは、同じ操作を実行しますが、明示的なクロージャを取る代わりに、それは @autoclosure 属性でそのパラメータの型をマークすることによってオートクロージャを取ります。それが クロージャではなく、String 引数を取ったかのように、今や、関数を呼び出すことができます。 customerProvider のパラメータの型が @autoclosure 属性でマークされているため、引数は自動的に、クロージャに変換されます。


  1. // customersInLine is ["Ewa", "Barry", "Daniella"]
  2. func serve(customer customerProvider: @autoclosure () -> String) {
  3.         print("Now serving \(customerProvider())!")
  4. }
  5. serve(customer: customersInLine.remove(at: 0))
  6. // Prints "Now serving Ewa!"


注意: オートクロージャの乱用はあなたのコードを理解するのを難しくします。コンテキスト(文脈)と関数名は、評価が延期されていることを明確にする必要があります。

エスケープするのを許可されているオートクロージャが欲しい場合は、@autoclosure@escaping 属性の両方を使用します。@escaping 属性は上記の クロージャのエスケープ で説明しています。


  1. // customersInLine is ["Barry", "Daniella"]
  2. var customerProviders: [() -> String] = []
  3. func collectCustomerProviders(_ customerProvider: @autoclosure @escaping () -> String) {
  4.         customerProviders.append(customerProvider)
  5. }
  6. collectCustomerProviders(customersInLine.remove(at: 0))
  7. collectCustomerProviders(customersInLine.remove(at: 0))
  8. print("Collected \(customerProviders.count) closures.")
  9. // Prints "Collected 2 closures."
  10. for customerProvider in customerProviders {
  11.         print("Now serving \(customerProvider())!")
  12. }
  13. // Prints "Now serving Barry!"
  14. // Prints "Now serving Daniella!"


上記のコードでは、その customerProvider 引数として渡されたクロージャを呼び出す代わりに、collectCustomerProviders(_:) 関数は customerProviders 配列にクロージャを追加します。配列は、関数の範囲外で宣言されており、それは配列の中のクロージャが関数から戻った後に実行できることを意味します。その結果、customerProvider 引数の値は、関数の範囲をエスケープすることを許されていなければなりません。





前:関数 次:列挙型
目次
Xcode 9 の新機能

Swift:はじめに
Swift と Cocoa と Objective-C
Swift Blog より

  • ようこそ Swift へ(Part I)
  • Swift について
  • バージョン互換性
  • Swift のツアー
  • 単純な値
    制御フロー
    関数とクロージャ
    オブジェクトとクラス
    列挙型と構造体
    プロトコルと拡張機能
    エラー処理
    汎用(ジェネリック)
  • Swift 言語のガイド(Part II)
  • Swift の基本
  • 定数と変数
  • 定数と変数の宣言
    型注釈
    定数と変数の命名
    定数と変数の印刷
    コメント
    セミコロン
  • 整数
  • 整数の境界
    Int
    UInt
    浮動小数点数
    安全な型と型推論
    数値リテラル
  • 数値型変換
  • 整数変換
    整数と浮動小数点間の変換
    型エイリアス
    ブール型
    タプル
  • Optional
  • nil
    if 文と強制開封
    Optional の結合
    暗黙に開封された Optionals
    エラー処理
  • アサーション(断言)と前提条件
  • アサーションを使用したデバッグ
    前提条件の実施
  • 基本演算子
  • 専門用語
    代入演算子
  • 算術演算子
  • 剰余演算子
    単項マイナス演算子
    単項プラス演算子
    複合代入演算子
    比較演算子
    三項条件演算子
    Nil 合体演算子
  • 範囲演算子
  • 閉鎖範囲演算子
    半開放範囲演算子
    片方の範囲
  • 論理演算子
  • 論理 NOT 演算子
    論理 AND 演算子
    論理 OR 演算子
    論理演算子の組み合わせ
    明示的な括弧
  • 文字列と文字
  • 文字列リテラル
    複数行の文字列リテラル
    文字列リテラル内の特殊文字
    空の文字列の初期化
    文字列の可変性
    文字列は値の型
    文字を使った作業
    文字列と文字を連結
    文字列補間
  • ユニコード(Unicode)
  • Unicode スカラー
    文字列リテラルの中の特別の文字
    拡張書記クラスタ
    文字を数える
  • 文字列のアクセスと変更
  • 文字列のインデックス
    部分文字列
    挿入と削除
  • 文字列の比較
  • 文字列と文字の等価性
    接頭辞と接尾辞の等価性
  • 文字列の Unicode 表現
  • UTF-8 の表現
    UTF-16 表現
    Unicode のスカラー表現
  • コレクション型
  • コレクションの可変性
  • 配列
  • 配列型省略構文
    空の配列の作成
    デフォルト値を持つ配列の作成
    2つの配列を共にして一つの配列に
    配列リテラルでの配列の作成
    配列へのアクセスと変更
    配列の繰り返し処理
  • セット
  • セット型のハッシュ値
    セット型の構文
    空のセットの作成と初期化
    配列リテラルでセットの作成
    セットへのアクセスと変更
    セットを反復処理
  • セット操作の実行
  • 基本的なセットの操作
    セットの身分と等価性
  • Dictionary
  • Dictionary 型の省略型構文
    空の Dictionary を作成
    Dictionary リテラルで Dictionary の作成
    Dictionary のアクセスと変更
    Dictionary を繰り返し処理
  • フロー制御
  • For-In ループ
  • While ループ
  • While
    Repeat-While
  • 条件文
  • if 文
  • Switch
  • 暗黙の Fallthrough なし
    範囲の一致
    タプル(Tuples)
    値の結合
    Where
    複合した case
  • 制御転送文
  • Continue
  • Break
  • ループ文内の Break
    Switch 文内の Break
    Fallthrough
    ラベル付きの文
    早期終了
    API 利用可能性の確認
  • 関数
  • 関数の定義と呼び出し
  • 関数のパラメータと戻り値
  • パラメータなしの関数
    複数パラメータの関数
    戻り値なしの関数
    複数の戻り値を持つ関数
    optional のタプル型の戻り値
  • 関数引数のラベルとパラメータ名
  • 引数のラベルの指定
    引数ラベルの省略
    デフォルトのパラメータ値
    可変個引数のパラメータ
    In-Out パラメータ
  • 関数型
  • 関数型の使用
    パラメータ型としての関数型
    戻り値の型としての関数型
    入れ子になった関数
  • クロージャ
  • クロージャ式
  • ソートするメソッド
    クロージャ式の構文
    文脈から型を推論
    単一式クロージャからの暗黙的戻り値
    引数名の省略
    演算子メソッド
    後続クロージャ
    値のキャプチャ
    クロージャは参照型
    クロージャのエスケープ
    オートクロージャ
  • 列挙型
  • 列挙型の構文
    switch 文で列挙型の値の一致
    関連する値
  • 生の値
  • 暗黙に割り当てられた生の値
    生の値からの初期化
    再帰的な列挙型
  • クラスと構造体
  • クラスと構造体を比較
  • 定義の構文
    クラスと構造体のインスタンス
    プロパティにアクセス
    構造体型のためのメンバー化イニシャライザ
    構造体と列挙型は値型
  • クラスは参照型
  • ID 演算子
    ポインタ
    クラスと構造体の間の選択
    文字列、配列、辞書の代入とコピーの動作
  • プロパティ
  • 格納されたプロパティ
  • 定数構造体インスタンスの格納されたプロパティ
    遅延した格納されたプロパティ
    格納されたプロパティとインスタンス変数
  • 計算されたプロパティ
  • セッタ宣言の省略形
    読み取り専用の計算されたプロパティ
    プロパティ監視者
    グローバルとローカル変数
  • 型プロパティ
  • 型プロパティの構文
    型プロパティの照会と設定
  • メソッド
  • インスタンスメソッド
  • self プロパティ
    インスタンスメソッド内から値の型を変更
    変異メソッド内で self に代入
    型メソッド
  • サブスクリプト
  • サブスクリプトの構文
    サブスクリプトの使用法
    サブスクリプトのオプション
  • 継承
  • 基本クラスの定義
    サブクラス化
  • オーバーライド(上書き)
  • スーパークラスメソッド、プロパティ、サブスクリプトへのアクセス
    オーバーライドするメソッド
  • オーバーライドするプロパティ
  • プロパティのゲッタとセッタのオーバーライド
    プロパティ監視者のオーバーライド
    オーバーライドの防止
  • 初期化
  • 格納されたプロパティの初期値を設定
  • イニシャライザ
    デフォルトのプロパティ値
  • 初期化のカスタマイズ
  • 初期化パラメータ
    パラメータ名と引数ラベル
    引数ラベルのないイニシャライザのパラメータ
    Optional のプロパティ型
    初期化中に定数プロパティへの代入
  • デフォルトのイニシャライザ
  • 構造体型のためのメンバ化イニシャライザ
    値型のイニシャライザデリゲート
  • クラスの継承と初期化
  • 指定イニシャライザとコンビニエンスイニシャライザ
    指定とコンビニエンスイニシャライザの構文
    クラス型のイニシャライザデリゲート
    二相の初期化
    イニシャライザ継承とオーバーライド
    自動イニシャライザの継承
    実際の指定とコンビニエンスイニシャライザ
  • 失敗可能イニシャライザ
  • 生の値を持つ列挙型のための失敗可能イニシャライザ
    初期化失敗の伝播
    失敗可能イニシャライザのオーバーライド
    init! の失敗可能イニシャライザ
    必須イニシャライザ
    クロージャや関数でのデフォルトのプロパティ値設定
  • デイニシャライザ
  • デイニシャライザはどのように働くか
    作動中のデイニシャライザ
  • Optional の連鎖
  • 強制開封の代替としての Optional の連鎖
    Optional の連鎖のモデルクラスの定義
    Optional の連鎖を使用したプロパティへのアクセス
    Optional の連鎖を通じてメソッドを呼び出す
  • Optional の連鎖を通じてサブスクリプトへのアクセス
  • Optional 型のサブスクリプトにアクセス
    連鎖の複数レベルのリンク
    optional の戻り値を持つメソッドでの連鎖
  • エラー処理
  • エラーの表現と Throw
    エラーの処理
    throw 関数を使用したエラーの伝播
    Do-Catch を使用したエラー処理
    エラー をOptional の値に変換
    エラー伝播を無効に
    クリーンアップアクションの指定
  • 型キャスト
  • 型キャストのためのクラス階層の定義
    型のチェック
    ダウンキャスト
  • Any と AnyObjecgt 用の型キャスティング
  • ネストした型
  • 実際のネストした型
    ネストした型への参照
  • 拡張機能
  • 拡張機能の構文
    計算されたプロパティ
    イニシャライザ
  • メソッド
  • 変異インスタンスメソッド
    サブスクリプト
    ネストした型
  • プロトコル
  • プロトコルの構文
    プロパティの要件
    メソッドの要件
    変異メソッドの要件
  • イニシャライザの要件
  • プロトコルイニシャライザ要件のクラス実装
    失敗可能イニシャライザの要件
    型としてのプロトコル
    デリゲート
  • 拡張機能を持つプロトコル準拠の追加
  • 拡張機能を持つプロトコルの採用を宣言
    プロトコル型のコレクション
    プロトコルの継承
    クラス専用プロトコル
    プロトコルの構成
    プロトコル準拠の確認
    Optional のプロトコル要件
  • プロトコル拡張機能
  • デフォルトの実装の提供
    プロトコル拡張機能に制約を追加
  • ジェネリック(汎用)
  • 汎用が解決する問題
    汎用関数
    型パラメータ
    型パラメータの命名
    汎用の型
    汎用型の拡張
  • 型の制約
  • 型制約の構文
    実際の型の制約
  • 関連型
  • 実際の関連型
    既存の型を拡張して関連型を指定
    型注釈を使用して関連型を制約
    汎用の Where 句
    汎用の Where 句を含む拡張機能
    関連する型と汎用の Where 句
    汎用のサブスクリプト
  • 自動参照カウント
  • どのように ARC は働くか
    実際の ARC
    クラスインスタンス間の強い循環参照
  • クラスインスタンス間の強い循環参照の解決
  • 弱い参照
    所有されていない参照
    所有されていない参照と暗黙に開封された Optional のプロパティ
    クロージャの strong な循環参照
  • クロージャの strong な循環参照の解決
  • キャプチャリストの定義
    弱い参照と所有されていない参照
  • メモリの安全性
  • メモリへのアクセス競合の理解
    メモリアクセスの特徴
    In-Out パラメータへのアクセスの競合
    メソッド内の Self へのアクセスの競合
    プロパティへのアクセスの競合
  • アクセス制御
  • モジュールとソースファイル
  • アクセスレベル
  • アクセスレベルの全体的指針
    デフォルトのアクセスレベル
    ターゲット一つのアプリのアクセスレベル
    フレームワークのアクセスレベル
    ユニットテストのターゲット用のアクセスレベル
    アクセス制御の構文
  • カスタム型
  • タプル型
    関数型
  • 列挙型
  • 生の値と関連する値
    ネストした型
    サブクラス化
  • 定数、変数、プロパティ、およびサブスクリプト
  • ゲッタとセッタ
  • イニシャライザ
  • デフォルトのイニシャライザ
    構造体型用のデフォルトメンバ化イニシャライザ
  • プロトコル
  • プロトコルの継承
    プロトコルの準拠
  • 拡張機能
  • 拡張機能の private メンバ
    汎用
    型エイリアス
  • 高度な演算子
  • ビット単位演算子
  • ビット単位の NOT 演算子
    ビット単位の AND 演算子
    ビット単位の OR 演算子
    ビット単位の XOR 演算子
  • ビット単位の左と右シフト演算子
  • 符号なし整数のシフト動作
    符号付き整数のシフト動作
  • オーバーフロー演算子
  • 値オーバーフロー
    優先順位と結合性
  • 演算子メソッド
  • 接頭辞と接尾辞演算子
    複合代入演算子
    等価演算子
  • カスタム演算子
  • カスタム挿入辞演算子の優先順位
  • 言語のガイド(Part III)
  • 言語リファレンスについて
  • 文法の読み方
  • 語彙の構造
  • 空白とコメント
    識別子
    キーワードと句読点
  • リテラル
  • 整数リテラル
    浮動小数点リテラル
    文字列のリテラル
    演算子

  • 型注釈
    型識別子
    タプル型
    関数型
    エスケープしないクロージャの制限事項
    配列型
    辞書型
    Optional の型
    暗黙に開封された Optional の型
    プロトコル構成の型
    メタタイプ型
    型の継承句
    型の推測

  • 接頭辞式
    Try 演算子
  • 二項式
  • 代入演算子
    三項条件演算子
    型キャスト演算子
  • 一次式
  • リテラル式
    Self 式
    スーパークラス式
  • クロージャ式
  • キャプチャ・リスト
    暗黙のメンバ式
    括弧で囲まれた式
    タプル式
    ワイルドカード式
    キーパス式
    セレクタ式
    キーパス文字列式
  • 接尾辞の式
  • 関数呼び出し式
    イニシャライザ式
    明示的なメンバ式
    接尾辞の Self 式
    サブスクリプト 式
    強制値の式
    Optional の連鎖式

  • ループ文
  • For-In 文
    While 文
    Repeat-While 文
  • 分岐文
  • if 文
    Guard 文
  • switch 文
  • switch 文は、網羅的である必要あり
    実行が暗黙的に case を Fall Through しない
    ラベル付き文
  • 制御転送文
  • break 文
    continue 文
    fallthrough 文
    return 文
    throw 文
    defer 文
    do 文
  • コンパイラ制御文
  • 条件コンパイルブロック
    行制御文
    利用可能条件
  • 宣言
  • トップレベルのコード
    コードブロック
    Import 宣言
    ­定数の宣言
  • 変数の宣言
  • 格納された変数と格納された変数のプロパティ
    計算された変数と計算されたプロパティ
    格納された変数監視者とプロパティの監視者
    型変数プロパティ
    型エイリアス宣言
  • 関数の宣言
  • パラメータ名
    In-Out パラメータ
    パラメータの特殊な種類
    メソッドの特殊な種類
    Throw する関数とメソッド
    Rethrow する関数とメソッド
    決して返さない関数
  • 列挙型の宣言
  • 任意の型の case を列挙
  • 間接による列挙
    生の値型の case を列挙
    列挙型 case へのアクセス
    構造体の宣言
    クラスの宣言
  • プロトコルの宣言
  • プロトコル・プロパティ宣言
    プロトコル・メソッド宣言
    プロトコル・イニシャライザ宣言
    プロトコル・サブスクリプト宣言
    プロトコルに関連した型の宣言
  • イニシャライザ宣言
  • 失敗可能イニシャライザ
    デイニシャライザ宣言
    拡張機能の宣言
    サブスクリプト宣言
    演算子の宣言
    優先順位グループ宣言
  • 宣言修飾子
  • アクセス制御レベル
  • 属性
  • 宣言の属性
  • インターフェイスビルダーで使われる宣言属性
    型の属性
  • パターン
  • ワイルドカードパターン
    識別子パターン
    値結合パターン
    タプルパターン
    列挙型 case パターン
    Optional のパターン
    型キャストパターン
    式のパターン
  • 汎用パラメータと引数
  • 汎用パラメータ句
  • 汎用の where 句
    汎用引数句
  • 文法のまとめ
  • 語彙の構造



    宣言
    属性
    パターン
    汎用パラメータと引数
  • マニュアルの変更履歴
  • 変更履歴