0Pricing
Swift Academy · レッスン

参照による値のキャプチャ

クロージャが周囲の状態をキャプチャする方法を理解します。

「参照による値のキャプチャ」はCoddyKit上の無料Swift Academyレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはSwift Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Swift Academyコースには全4レッスンが含まれています。

クロージャーがキャプチャするもの

クロージャーは、参照している周囲のスコープにある変数や定数をキャプチャします。キャプチャされた変数は参照によって保持されるため、クロージャーから後の変更を確認できます。

定数のキャプチャ

関数が戻った後も、クロージャーはgreetingを記憶しています:

func makeGreeter() -> () -> String {
    let greeting = "Hello"
    return { greeting }
}
let greet = makeGreeter()
print(greet())  // "Hello"

変数を参照でキャプチャする

countはvarなので、クロージャーは呼び出しをまたいで同じ記憶領域を変更します:

func makeCounter() -> () -> Int {
    var count = 0
    return {
        count += 1
        return count
    }
}
let next = makeCounter()
print(next(), next(), next())  // 1 2 3

共有される記憶領域

2つのクロージャーが同じ変数をキャプチャし、お互いの変更を確認できます:

func makePair() -> (() -> Void, () -> Int) {
    var value = 0
    let inc = { value += 1 }
    let read = { value }
    return (inc, read)
}
let (inc, read) = makePair()
inc(); inc()
print(read())  // 2

キャプチャには後の変更が反映されます

クロージャーは、作成時の値ではなく、呼び出し時点での変数の現在の値を読み取ります:

var message = "first"
let show = { print(message) }
message = "second"
show()  // "second"

参照によるキャプチャと値によるキャプチャ

デフォルトでは、変更可能な変数は参照によってキャプチャされます。作成時点の値を固定したコピーが必要な場合は、キャプチャリストに[x]のように記述します。

値を固定する

キャプチャリストは値をすぐにコピーします:

var n = 10
let frozen = { [n] in n }   // copies 10 now
n = 99
print(frozen())  // 10

クロージャーごとに独立した状態

ファクトリを呼び出すたびに、新しくキャプチャされた変数が作られます:

func counter() -> () -> Int {
    var c = 0
    return { c += 1; return c }
}
let a = counter(), b = counter()
print(a(), a(), b())  // 1 2 1

ループ内でのキャプチャ

注意しないと、ループ内のクロージャーが同じ変数を共有することがあります。反復ごとの値を保存するには、キャプチャリストを使います:

var closures: [() -> Int] = []
for i in 1...3 {
    closures.append { [i] in i }
}
print(closures.map { $0() })  // [1, 2, 3]

メソッド内で self をキャプチャする

メソッド内で作成されたクロージャーは、周囲のインスタンスをキャプチャするため、後からプロパティを読み取ったり変更したりできます:

class Bank {
    var balance = 0
    func deposit() -> () -> Void {
        return { self.balance += 10 }
    }
}
let bank = Bank()
let add = bank.deposit()
add(); add()
print(bank.balance)  // 20

なぜ重要なのか

参照によるキャプチャは、カウンター、アキュムレーター、状態を持つコールバックを実現します — 一方で、クロージャーがオブジェクトを生存させ続けることもあるため、次にキャプチャリストを使って管理します。

func accumulator() -> (Int) -> Int {
    var total = 0
    return { total += $0; return total }
}
let add = accumulator()
print(add(10), add(5))  // 10 15

クイックチェック

クロージャーは、変更可能な変数をデフォルトでどのようにキャプチャしますか?

まとめ

キャプチャの仕組みを学びました:

  • クロージャーは、スコープ内で参照されている変数をキャプチャします
  • 変更可能なvarは参照によってキャプチャされるため、変更や変更操作が共有されます
  • キャプチャリスト[x]を使うと、作成時点の値のコピーを固定できます
  • これにより、カウンターや状態を持つコールバックを実現できます

次は、エスケープするクロージャーです。

よくある質問

「参照による値のキャプチャ」レッスンは無料ですか?

はい。「参照による値のキャプチャ」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Swift Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Swift Academyコースには全4レッスンが含まれています。

「参照による値のキャプチャ」で何を学びますか?

クロージャが周囲の状態をキャプチャする方法を理解します。 ブラウザで直接実行するハンズオンコードでSwift Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Swift Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのSwift Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。

「参照による値のキャプチャ」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このSwift Academyレッスンでコードを書いて実行できますか?

はい。すべてのSwift Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. 参照による値のキャプチャ
  2. エスケapingクロージャ
  3. キャプチャリストとweak self
  4. オートクロージャ
← Swift Academyに戻る