クロージャとは?
CoddyのLuaジャーニー「ロジックと制御フロー」セクションの一部。レッスン 14/54。
関数は変数に格納したり、引数として渡したり、他の関数から返したりできることを学びました。ここでは、このことから生じる最も強力な結果の一つであるクロージャについて詳しく見ていきます。
クロージャは、入れ子になった function が、それを囲む function の local 変数を「覚えている」状態になることで発生します。外側の function の実行が完了した後でも、その変数を保持しています。これは最初は奇妙に聞こえるかもしれません。変数を作成した function の処理が終わった後も、その変数が存在し続けることなど、どうして可能なのでしょうか?
この概念を示す簡単な例を見てみましょう:
function createCounter()
local count = 0
return function()
count = count + 1
return count
end
end
local counter = createCounter()
print(counter()) -- 出力: 1
print(counter()) -- 出力: 2
print(counter()) -- 出力: 3createCounter()が呼び出されると、local 変数 countを作成し、匿名の function を返します。通常、createCounter()が終了するとcountは消えると思うでしょう。しかし、返された function は引き続きcountにアクセスできます。その変数を「クロージャとして取り込む」のです。
counter()を呼び出すたびに、createCounter()が最初に実行されたときに作成された同じcount変数にアクセスし、その値を変更します。内部の function は自身の環境を保持するため、呼び出しと呼び出しの間でも状態が維持されます。
チャレンジ
簡単特定のfactorを持つmultiplier functionを作成するcreateMultiplierを書き、その後すぐにそれを使って指定されたnumberを乗算してください。
ロジック:
createMultiplierの内部に、numberパラメーターを受け取るネストされたfunctionを作成する- ネストされたfunctionは、そのパラメーターに外側のfunctionの
factorを掛ける必要がある - ネストされたfunctionはクロージャを形成し、
factorの値を記憶する - multiplier functionを
numberパラメーターで呼び出し、結果を返す
パラメーター:
factor(number): multiplierの値number(number): 乗算するnumber
戻り値:
numberにfactorを掛けた結果(number)
自分で試してみよう
function createMultiplier(factor, number)
local multiply = function(x)
return x * factor
end
-- 以下で multiply 関数を使用する
endこのレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
ロジックと制御フローのすべてのレッスン
自分で練習してみよう: Luaオンラインコンパイラ