Возможно ли в lua выполнить функцию из строки, представляющей ее имя?
i.e: У меня есть string x = "foo"
, можно ли сделать x()
?
Если да, то какой синтаксис?
Возможно ли в lua выполнить функцию из строки, представляющей ее имя?
i.e: У меня есть string x = "foo"
, можно ли сделать x()
?
Если да, то какой синтаксис?
Вызов функции в глобальном пространстве имен (как указано в @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
loadstring
здесь не ответ. Для начала вам понадобится return
в строке, а другие детали я не буду вдаваться.
THC4k имеет правильную идею; если у вас есть имя функции в переменной x, то нужный вам вызов
_G[x](arg1, arg2, ...)
Я часто добавляю кучу функций в таблицу:
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']
.
Имена не уникальны, может быть много имен функций foo в разных пространствах имен. Но foo
в глобальном пространстве имен.
Похоже, вы хотите сделать "eval", который поддерживается в Lua так:
assert(loadstring(x))()
Скорее всего, вы захотите объединить "()" на x сначала.