5

Lua初心者です。関数参照をキーとして Lua テーブルに保存できますか? これに似たもの:

local fn = function() print('hello') end
local my_table = {}
my_table[fn] = 123

これはうまくいくようですが、関数参照の一意性に依存できるかどうかはわかりません。関数参照がスコープ外になると、Lua は関数参照を再利用できますか? これにより問題が発生する可能性がありますか、それとも何らかの理由で悪い習慣と見なされますか?

4

4 に答える 4

6

うん。luaで私が遭遇した最高のものの1つは、参照プロパティとしての何かです。

keyテーブルでのsの使用方法に問題はありません。

LuaPiLから

Luaのテーブルは値でも変数でもありません。それらはオブジェクトです。テーブルは動的に割り当てられたオブジェクトと考えることができます。プログラムは、それらへの参照(またはポインター)のみを操作します。舞台裏で隠されたコピーや新しいテーブルの作成はありません。

あなたの例では、関数に引数を渡していないので、基本的に、プログラムで参照として関数を使用することは無意味です。一方、次のようなものです。

fn1 = function(x) print(x) end
fn2 = function(x) print("bar") end
t[fn1] = "foo"
t[fn2] = "foo"
for i, v in pairs(t) do i(v) end

その用途があります。

スコープ外になった関数参照をLuaは再利用できますか?

親テーブルがスコープ内にある限り、はい。テーブルは作成および操作されますがコピーされないため、関数参照がテーブルインデックスメモリから非推奨になる可能性はありません。この回答も実際に試した後、後で編集します。

これは問題を引き起こす可能性がありますか、それとも何らかの理由で悪い習慣と見なされますか?

Cなどの他の言語に精通しているユーザーは、pythonテーブルを読み取るときに配列を念頭に置く傾向があるため、これは悪い習慣と見なされています。ではそのような心配はなく、プログラムは完璧に機能します。

関数参照の一意性に依存できるかどうかはわかりません。

なんで?

于 2013-01-28T14:22:06.153 に答える
3

関数参照の一意性は、Lua のバージョンによって異なります。

Lua 5.2 のマニュアルには次のように書かれています。
a function definition may not create a new value; it may reuse some previous value if there is no observable difference to the new function

例:

-- 10 different function references on Lua 5.1
-- The same function reference for Lua 5.2
local j
for i = 1, 10 do
   print(function() print(j) end)
end

-- 10 different function references for any Lua version
for i = 1, 10 do
   print(function() print(i) end)
end

したがって、ルールは次のとおりです。異なる参照を取得するには、異なるクロージャーを作成します。

于 2013-01-29T00:32:59.027 に答える
1

これはうまく機能しているように見えますが、関数参照の一意性に依存できるかどうかはわかりません。

すべてfunction() endのステートメントは、新しいクロージャーを作成します。関数の実際のコードは、同じコンストラクターからのものである場合に再利用されます。

for i=1,100 do
    t[function() print(i) end] = i -- this function body will be reused
end

ただし、各クロージャは一意であり、それが参照用に重要です。

スコープ外になった関数参照をLuaは再利用できますか?

fnのキーとして使用されている限り、Luaは収集しませんmy_table。テーブルと関数の両方が収集されるように範囲外になった場合my_tableでも、Luaが参照を再利用しても影響はありません。いずれにせよ、あなたは元気です。

于 2013-01-28T17:53:15.250 に答える
1

それを行うことができ、function(ガベージコレクターによって) 破棄されるまでメモリの同じ場所に残ります。

インタラクティブで試すことができますlua

> fn = function() print('hello') end
> print(fn)
function: 0x9d058d0

> fn2 = function() print('hello') end
> print(fn2)
function: 0x9d05ee8

> fn2=fn
> print(fn2)
function: 0x9d058d0

> print(function() print('hello') end)
function: 0x9d068a8

> print(function() print('hello') end)
function: 0x9d06bf8

範囲外になるとガベージコレクションされることに注意してfnください。あなたの場合、同じブロックにあるので問題にはlocalなりません。ローカル変数に関する Lua のドキュメントを参照してください。my_tablelocal

于 2013-01-28T14:23:43.523 に答える