在lua中是否可以从表示其名称的字符串执行函数?
即:我有string x = "foo"
,是否可以x()
?
如果是,语法是什么?
答案 0 :(得分:35)
调用全局命名空间中的函数(如@ THC4k所述)很容易完成,不需要loadstring()
。
x='foo'
_G[x]() -- calls foo from the global namespace
如果函数在另一个表中,则需要使用loadstring()
(或遍历每个表),例如x='math.sqrt'
。
如果使用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
答案 1 :(得分:10)
我经常把一堆函数放在表格中:
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']
。
答案 2 :(得分:9)
loadstring
不是这里的答案。对于初学者,你需要在字符串中加return
,其他细节我不会进入。
THC4k有正确的想法;如果你在变量x中有函数名,那么你想要的调用是
_G[x](arg1, arg2, ...)
答案 3 :(得分:4)
名称不是唯一的,在不同的名称空间中可以有许多函数名称foo。但是_G['foo']
在全局命名空间中是foo
。
答案 4 :(得分:1)
听起来你想要做一个'eval',Lua支持这样:
assert(loadstring(x))()
但是,您可能希望首先将“()”连接到x上。