Подтвердить что ты не робот

Функция вызова lua из строки с именем функции

Возможно ли в lua выполнить функцию из строки, представляющей ее имя?
i.e: У меня есть string x = "foo", можно ли сделать x()?

Если да, то какой синтаксис?

4b9b3361

Ответ 1

Вызов функции в глобальном пространстве имен (как указано в @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

Ответ 2

loadstring здесь не ответ. Для начала вам понадобится return в строке, а другие детали я не буду вдаваться.

THC4k имеет правильную идею; если у вас есть имя функции в переменной x, то нужный вам вызов

_G[x](arg1, arg2, ...)

Ответ 3

Я часто добавляю кучу функций в таблицу:

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'].

Ответ 4

Имена не уникальны, может быть много имен функций foo в разных пространствах имен. Но foo в глобальном пространстве имен.

Ответ 5

Похоже, вы хотите сделать "eval", который поддерживается в Lua так:

assert(loadstring(x))()

Скорее всего, вы захотите объединить "()" на x сначала.