使用函数名称的字符串调用Lua函数。

在Lua中,是否可以根据表示其名称的字符串执行函数?

也就是说,如果有字符串 x = "foo",是否可以执行 x()

如果可以,语法是什么?

原文链接 https://stackoverflow.com/questions/1791234

点赞
stackoverflow用户95612
stackoverflow用户95612
Names are not unique, there can be many functions names `foo` in different namespaces. But `_G['foo']` is `foo` in the global namespace.

变量名不是唯一的,不同的命名空间中可能会有许多名为 foo 的函数。但是 _G['foo'] 是全局命名空间中的 foo

2009-11-24 16:35:45
stackoverflow用户10601
stackoverflow用户10601

听起来你想要执行一个'eval',在Lua中可以这样实现:

assert(loadstring(x))()

不过你可能需要先将“()”与x连接起来。

2009-11-24 16:35:51
stackoverflow用户41661
stackoverflow用户41661

loadstring 在这里不是答案。首先,您需要在字符串中使用 return,还有其他细节我不会深入探讨。

THC4k 的想法是正确的;如果您将函数名称存储在变量 x 中,则所需的调用是

_G[x](arg1, arg2, ...)
2009-11-24 16:55:35
stackoverflow用户173806
stackoverflow用户173806

调用全局命名空间中的函数(如 @THC4k 所述)很容易实现,不需要使用 loadstring()

x='foo'
_G[x]() -- 从全局命名空间调用 foo

如果函数在其他 table 中,例如 x='math.sqrt',则需要使用 loadstring()(或遍历每个 table)。

如果使用 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
2009-11-24 17:09:26
stackoverflow用户594745
stackoverflow用户594745

我经常将一堆函数放在一个表格中:

functions = {
  f1 = function(arg) print("函数一:"..arg) end,
  f2 = function(arg) print("函数二:"..arg..arg) end,
  ...,
  fn = function(arg) print("函数 N:argh") end,
}

然后,您可以将字符串用作表索引,并像这样运行函数

print(functions["f1"]("blabla"))
print(functions["f2"]("blabla"))

这是结果:

函数一:blabla
函数二:blablablabla

我认为这比使用 loadstring() 更清晰。如果您不想创建一个特殊的函数表格,可以使用 _G['foo']

2011-01-29 06:07:16