Trailing Closures
CoddyのSwiftジャーニー「ロジックとフロー」セクションの一部 — レッスン 39/56。
クロージャが関数の最後の引数である場合、かっこの外側に記述することができます。これは後置クロージャ(trailing-closure)形式と呼ばれ、Swiftのコードを自然に読みやすくするための書き方です。
let nums = [1, 2, 3]
// 標準的な形式
let a = nums.map({ $0 * 2 })
// 後置クロージャ形式
let b = nums.map { $0 * 2 }クロージャが唯一の引数である場合、括弧も省略されます。そのため、これまで見てきたものはすべて、独自の制御構造のように見えます。
同様に、クロージャを引数に取る独自の関数を作成することもできます。
func repeatN(_ n: Int, action: () -> Void) {
for _ in 0..<n {
action()
}
}
repeatN(3) {
print("hi")
}後置クロージャの形式により、repeatN(3) { ... } は組み込みのループのように読めるようになります。それが重要な点です。自分で構築した制御構造が、標準ライブラリのものとまったく同じように見えるのです。
チャレンジ
簡単関数 collect を次のように定義してください:
- 整数
nとクロージャbuilder: (Int) -> Stringを受け取ります 1からnまで(両端を含む)の各iに対してbuilderを呼び出し、結果の文字列の配列を返します
標準入力から整数を読み込み、その整数を使用して collect を呼び出します。その際、各値に対して "i=<i>" を生成する後置クロージャを使用し、結合した結果を , で区切って出力してください。
入力が 4 の場合、出力は i=1,i=2,i=3,i=4 となります。
チートシート
後置クロージャ構文 (Trailing closure syntax): クロージャが最後の引数である場合、括弧の外側に記述することができます。それが唯一の引数である場合、括弧は完全に省略されます。
let nums = [1, 2, 3]
let a = nums.map({ $0 * 2 }) // 標準的
let b = nums.map { $0 * 2 } // 後置クロージャカスタム関数も同様にクロージャを受け取ることができ、組み込みの制御構造のように読み取れるようになります:
func repeatN(_ n: Int, action: () -> Void) {
for _ in 0..<n {
action()
}
}
repeatN(3) {
print("hi")
}自分で試してみよう
let n = Int(readLine()!)!
// TODO: func collect(_ n:Int, builder:(Int)->String) -> [String]
// その後 collect(n) { ... } を呼び出し、"," で結合して出力する
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。