Scalaでクロージャする超簡単なサンプル。
package sample object ClosureSample extends Application { def makeCounter() = { var count = 0; () => { count += 1 count } } var count = 100; val counter = makeCounter() println(counter()) println(counter()) println(counter()) val counter2 = makeCounter() println("------------") println(counter2()) }
実行結果。
1 2 3 ------------ 1
makeCounterは関数を返す関数。() => {}は引数なしの無名関数。
この無名関数からmakeCounterのローカル変数であるcountが見えるところがクロージャのミソ。
countはクロージャを作成するたびに別の変数となるので、counter()呼び出しとcounter2()呼び出しでは出力する値が異なっている。
こうすることで無名関数から利用する変数を局所化できるってことだね。
レキシカルスコープとは?
クロージャの説明でよく一緒に出てくるレキシカルスコープとは、関数の構造から変数のスコープと生存期間が決まるような性質のこと。
makeCounter()のローカル変数countは戻り値の無名関数が参照されている間(関数からcountを参照するので)GCされずに生存する。