その名前を表す文字列から関数を実行することは可能ですか?
i.e:私は_string x = "foo"
_を持っていますが、x()
を実行できますか?
はいの場合、構文は何ですか?
@ THC4kで言及されているように、グローバル名前空間の関数を呼び出すのは簡単で、loadstring()
は必要ありません。
_x='foo'
_G[x]() -- calls foo from the global namespace
_
関数が別のテーブルにある場合、_x='math.sqrt'
_などの場合は、loadstring()
(または各テーブルをウォークする)を使用する必要があります。
loadstring()
を使用する場合は、括弧を楕円_(...)
_で追加してパラメーターを許可するだけでなく、return
を前に追加することもできます。
_x='math.sqrt'
print(assert(loadstring('return '..x..'(...)'))(25)) --> 5
_
またはテーブルを歩く:
_function findfunction(x)
assert(type(x) == "string")
local f=_G
for v in x:gmatch("[^%.]+") do
if type(f) ~= "table" then
return nil, "looking for '"..v.."' expected table, not "..type(f)
end
f=f[v]
end
if type(f) == "function" then
return f
else
return nil, "expected function, not "..type(f)
end
end
x='math.sqrt'
print(assert(findfunction(x))(121)) -->11
_
私は頻繁に関数の束をテーブルに入れました:
_functions = {
f1 = function(arg) print("function one: "..arg) end,
f2 = function(arg) print("function two: "..arg..arg) end,
...,
fn = function(arg) print("function N: argh") end,
}
_
次に、文字列をテーブルインデックスとして使用して、次のように関数を実行できます。
_print(functions["f1"]("blabla"))
print(functions["f2"]("blabla"))
_
これが結果です:
_function one: blabla
function two: blablablabla
_
これはloadstring()
を使用するよりもクリーンであることがわかりました。特別な関数テーブルを作成したくない場合は、__G['foo']
_を使用できます。
loadstring
はここでは答えではありません。まず、文字列にreturn
が必要ですが、その他の詳細については説明しません。
THC4kは正しい考えを持っています。変数xに関数名がある場合、必要な呼び出しは
_G[x](arg1, arg2, ...)
名前は一意ではなく、さまざまな名前空間に多くの関数名fooが存在する可能性があります。だが _G['foo']
は、グローバル名前空間のfoo
です。
Luaでサポートされている「評価」を実行したいようです:
assert(loadstring(x))()
ただし、おそらく最初に "()"をxに連結する必要があります。