クロージャ間で共有されるUpvalue
複数のクロージャで同じupvalueを共有する方法と、変更による影響を学びます。
「クロージャ間で共有されるUpvalue」はCoddyKit上の無料Lua Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはLua Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Lua Academyコースには全4レッスンが含まれています。
同じUpvalueの共有
同じスコープで定義された2つのクロージャは、まったく同じUpvalueセルを共有できます。一方による変更は、もう一方からも確認できます。
local function makeGetterSetter()
local value = 0
local function get() return value end
local function set(v) value = v end
return get, set
end
local get, set = makeGetterSetter()
set(42)
print(get()) -- 42共有が発生する理由
LuaはクロージャごとにUpvalueをコピーしません。同じブロック内で作成され、同じローカル変数を参照するすべてのクロージャは、1つのUpvalueセルを共有します。
共有UpvalueによるObserver Pattern
共有Upvalueは、複数のクロージャ間のメッセージバスとして機能します。
local count = 0
local inc = function() count = count + 1 end
local dec = function() count = count - 1 end
local get = function() return count end
inc(); inc(); dec()
print(get()) -- 1ループ変数に関する注意点
numeric forループでは、反復ごとに新しいローカルなループ変数が作成されるため、クロージャはそれぞれ独立したUpvalueをキャプチャします。
local fns = {}
for i = 1, 3 do
fns[i] = function() return i end
end
print(fns[1](), fns[2](), fns[3]()) -- 1 2 3 (each closure has its own i)whileループのループ変数に関する注意点
whileループで変化する1つの変数をクロージャで参照すると、すべてのクロージャが同じUpvalueを共有し、最後の値を確認することになります。
local fns = {}
local i = 0
while i < 3 do
i = i + 1
fns[i] = function() return i end -- all share same i!
end
print(fns[1]()) -- 3 (not 1!)新しいローカル変数のキャプチャ
whileループで独立した値をキャプチャするには、ループ本体の中で新しいローカル変数を導入します。
local fns = {}
local i = 0
while i < 3 do
i = i + 1
local ci = i -- new local per iteration
fns[i] = function() return ci end
end
print(fns[1]()) -- 1, fns[2]() == 2共有状態モジュールパターン
モジュールは、Upvalueを通じてプライベートな状態テーブルを共有する複数の関数を公開できます。
local function makeStack()
local data = {}
return {
push = function(v) data[#data+1] = v end,
pop = function() local v = data[#data]; data[#data]=nil; return v end,
size = function() return #data end,
}
endエイリアスと変更
注意してください。同じUpvalueを参照するすべてのクロージャは、同じ変更を即座に確認します。これは強力な仕組みですが、意図しない結合を引き起こすことがあります。
Upvalueの同一性
debug.upvalueid(f, n)は、関数fのn番目のUpvalueの一意な識別子を返します。同じUpvalue IDを持つ2つのクロージャは、同じセルを共有します。
debug.upvaluejoin
debug.upvaluejoin(f1, n1, f2, n2)を使うと、f1のn1番目のUpvalueが、f2のn2番目のUpvalueと同じセルを共有するようになります。デバッグ用の低レベルなツールです。
実践的なパターン
- プライベート変数を共有するGetter/Setterの組み合わせ
- 複数のクロージャからリセット機能を公開するイベントカウンター
- 複数のAPI関数で共有するモジュール状態
共有Upvalueに関する質問
同じスコープでgetとsetという2つのクロージャを作成し、どちらもvalueをキャプチャしています。set(99)を呼び出すと、get()は何を返しますか?
まとめ:共有Upvalue
同じスコープにあるクロージャは、Upvalueセルを共有します。変更は、共有しているすべてのクロージャから即座に確認できます。これは、Luaにおけるカプセル化とモジュール状態の基盤です。
よくある質問
「クロージャ間で共有されるUpvalue」レッスンは無料ですか?
はい。「クロージャ間で共有されるUpvalue」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Lua Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Lua Academyコースには全4レッスンが含まれています。
「クロージャ間で共有されるUpvalue」で何を学びますか?
複数のクロージャで同じupvalueを共有する方法と、変更による影響を学びます。 ブラウザで直接実行するハンズオンコードでLua Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Lua Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのLua Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。
「クロージャ間で共有されるUpvalue」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このLua Academyレッスンでコードを書いて実行できますか?
はい。すべてのLua Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- Upvalueとは
- クロージャ間で共有されるUpvalue
- ファクトリー関数とジェネレーター
- クロージャによるメモ化