関数の最後の引数として関数にクロージャ式を渡す必要があって、かつクロージャ式が長い場合には、後置クロージャとして記述すると効果的です。後置クロージャは、サポートする関数呼び出しの丸括弧の外側(後ろ)に記述されるクロージャ式です。
func someFunctionThatTakesAClosure(closure: () -> Void) {
// 関数本体
}
// 後置クロージャを使用せずに、この関数を呼び出す方法
someFunctionThatTakesAClosure({
// クロージャの本体
})
// 後置クロージャを使用して、この関数を呼び出す方法
someFunctionThatTakesAClosure() {
// 後置クロージャの本体
}
Closure Expression Syntax の文字列ソート用クロージャを、後置クロージャとして sort(_:)
メソッドの丸括弧の外側に記述することができます。
reversed = names.sort() { $0 > $1 }
クロージャ式が関数やメソッドの唯一の引数で、そのクロージャ式を後置クロージャとする場合には、関数を呼び出すときに関数名やメソッド名の後に丸括弧 ()
を記述する必要はありません。
reversed = names.sort { $0 > $1 }
クロージャがインラインで 1 行に記述するには長すぎるときに、後置クロージャは最も効果的です。例として、Swift の Array
型には引数 1 つのクロージャ式を受け取る map(_:)
メソッドがあります。クロージャは配列内の項目ごとに一度呼び出され、その項目にマッピングした別の(型が異なることもある)値を返します。マッピングの性質と戻り値の型は、指定するクロージャに委ねられています。
配列の各要素にクロージャを適用後、map(_:)
メソッドは元の配列での対応する値と同じ順序で、マッピングした新しい値をすべて含む新しい配列を返します。
これ以降は、Int
値の配列を String
値の配列に変換する後置クロージャを受け取る map(_:)
メソッドを使う方法です。配列 [16, 58, 510]
は、新しい配列 ["OneSix", "FiveEight", "FiveOneZero"]
を生成するために使用されます。
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]
このコードは、整数値と英語名をマッピングする辞書を生成しています。また、文字列に変換される整数値の配列を定義しています。
クロージャ式を後置クロージャとして配列の map(_:)
メソッドに渡すことで、String
値の配列を生成するために配列 numbers
を使用することができます。
let strings = numbers.map {
(number) -> String in
var number = number
var output = ""
while number > 0 {
output = digitNames[number % 10]! + output
number /= 10
}
return output
}
// strings は [String] 型と推論される
// その値は ["OneSix", "FiveEight", "FiveOneZero"]
map(_:)
メソッドは配列内の各項目ごとに一度クロージャ式を呼び出します。マップされる配列内の値から型を推論できるため、クロージャの入力パラメータ number
の型を指定する必要はありません。
この例では、変数 number
はクロージャの number
パラメータの値で初期化されているため、値をクロージャ本体で変更することができます。(関数およびクロージャのパラメータは常に定数です。)また、マップされる配列に格納される型を示すために、クロージャ式に戻り値の型 String
を指定しています。
クロージャ式は、呼び出されるたびに文字列 output
を構築します。剰余演算 (number % 10
) を使用して number
の最後の桁の数値を算出し、辞書 digitNames
から適切な文字列を調べるためにこの数値を使用します。文字列表現を生成するために、1 以上の整数をこのクロージャに使用することができます。
digitNames
のサブスクリプトを呼び出すときにエクスクラメーションマーク (!
) を付けます。上の例では、number % 10
が常に辞書 digitNames
の有効なサブスクリプトキーであることが確実なため、サブスクリプトが返すオプショナル値に格納された String
値を強制的にアンラップするために、エクスクラメーションマークを使用しています。
辞書 digitNames
から取得された文字列は、効果的に逆順で数値の文字列バージョンを構築するために、output
の前に追加されています。(式 number % 10
は、16
を 6
に、58
を 8
に、510
を 51
にします。)
そして、変数 number
は 10
で割られています。整数であるため割り算で切り捨てられ、16
が 1
に、58
が 5
に、510
が 51
になります。
number
が 0
になるまで処理が繰り返され、文字列 output
がクロージャから返され、map(_:)
メソッドによって配列に追加されます。
上で見た後置クロージャシンタックスの使用例は、map(_:)
メソッドの丸括弧でクロージャ全体を囲む必要がなく、関数のすぐ後にクロージャの機能をすっきりと記述してしています。
Portions of this page are translations based on work created and shared by Apple and used according to terms described in the Creative Commons Attribution 4.0 International License.