値のキャプチャ
CoddyのSwiftジャーニー「ロジックとフロー」セクションの一部。レッスン 40/56。
クロージャは、作成されたときにスコープ内にあった変数を記憶します。クロージャの本体は、後でそれらを読み取ったり、変更したりすることさえできます。それを囲む関数が戻った後であっても同様です。これはキャプチャと呼ばれます。
func makeCounter() -> () -> Int {
var count = 0
return {
count += 1
return count
}
}
let next = makeCounter()
print(next()) // 1
print(next()) // 2
print(next()) // 3makeCounter を呼び出すたびにまったく新しい count が得られるため、2つのカウンターが状態を共有することはありません。
let a = makeCounter()
let b = makeCounter()
print(a()) // 1
print(b()) // 1
print(a()) // 2キャプチャは、クロージャを単純な関数よりも強力にする仕組みです。クロージャは状態を保持します。JavaScript、Python、その他多くの言語でも、同じ仕組みを目にすることになるでしょう。
チャレンジ
中級小さなカウンターファクトリを作成してください。
makeCounter(start: Int, step: Int) という関数を定義し、() -> Int 型のクロージャを返してください。クロージャを呼び出すたびに次の値を返します。最初の呼び出しでは start、次では start + step、その次では start + 2*step が返され、以降も同様です。
入力から3つの整数、start、step、n を読み取ります。start と step を使ってカウンターを作成し、それを n 回呼び出して、すべての結果をそれぞれ別の行に出力してください。
入力が 5 / 3 / 4 の場合、出力は次のようになります。
5
8
11
14自分で試してみよう
let start = Int(readLine()!)!
let step = Int(readLine()!)!
let n = Int(readLine()!)!
// TODO: makeCounter(start:step:) -> () -> Int で実行中の値をキャプチャするもの
// 次にそれを n 回呼び出して各結果を出力する
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
ロジックとフローのすべてのレッスン
自分で練習してみよう: Swiftプレイグラウンド