https://docs.swift.org/swift-book/LanguageGuide/Closures.html
上記ページを読んでいていまいちスッキリしない状況なのですが、
まずCapturing Valuesの節で
Swift
1func makeIncrementer(forIncrement amount: Int) -> () -> Int { 2 var runningTotal = 0 3 func incrementer() -> Int { 4 runningTotal += amount 5 return runningTotal 6 } 7 return incrementer 8} 9 10let incrementByTen = makeIncrementer(forIncrement: 10) 11 12incrementByTen() 13// returns a value of 10 14incrementByTen() 15// returns a value of 20 16incrementByTen() 17// returns a value of 30 18
上記のようなよくあるカウンターのサンプルが示されています。
javascriptでもクロージャーのところでこのようなカウンターのサンプルはあり、動きもほぼ同じなので、コードの動きはだいたいわかるのですが、その下の節で
Closures Are Reference Types
とあり、クロージャーが参照型である解説が出てきます。
参照型の話でARC(自動参照カウント)ともつながってくると思うのですが、そこらへんを読んでいて、
クラスとクロージャーは参照型、
Int、Stringなどは構造体なので値型。
参照型はARCが適用されるが、値型は参照型ではないのでARCは適用されない。
みたいなことが
https://docs.swift.org/swift-book/LanguageGuide/AutomaticReferenceCounting.html
に書いてあると思います。
そこでキャプチャ(カウンターのサンプル)なのですが、外部の定数incrementByTenにincrementer関数がセットされ、関数incrementerはクロージャーなので参照型、ということでmakeIncrementer関数の実行が終了してもARCの仕組みにより、incrementByTenがincrementer関数を参照している間はincrementer関数が消されず、
incrementByTen()
とすることでincrementer関数が何度でも実行でき、状態を保持しているような挙動が実現できる、ということはわかるのです。
ただ、makeIncrementer内の変数runningTotalと引数amountは、本来makeIncrementer関数の実行が終わると消えてしまうものだと思うのですが、しかしincrementer関数によりキャプチャされているので、makeIncrementer関数実行終了後も消されずに、まるでカウンターが状態を保持しているような挙動を実現している、ということだと思うのですが、これはARCの仕組みと非常に似ていると思います。ただ、runningTotalとamountはどちらもInt型なので値型です。ARCの仕組みが適用されるのは参照型、という説明と食い違うのですが、キャプチャはARCの仕組みとは関係ない機能なのでしょうか?
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/12/26 10:22 編集