例如,我有一张表
table.insert( t, 1, function()
print ("rock");
end );
有没有办法从这个表中获取函数名称。我知道我可以像键一样存储名称,但如果我想保留数字索引并且我想知道函数名称怎么办? 有什么办法吗? 谢谢,提前。
答案 0 :(得分:6)
说你有这段代码:
t = {}
x = 5
table.insert(t, 1, x)
t
将为{[1] = 5}
。 “5”只是一个数字 - 它没有名称,并且与变量“x”无关;这是一个值
在Lua中,函数的处理方式与值:
t = {}
x = function() print("test! :D") end
table.insert(t, 1, x)
x的值不以任何方式,形状或形式与x相关联。如果要手动命名函数,可以将函数包装在表中,例如:
t = {}
x = function() print("test! :D") end
table.insert(t, 1, {
name = "MyFunctionName",
func = x
})
你就是这样做的!
... 除非 ..
..你违反了规则!
当Lua开发出来时,开发人员意识到,如果不是不可能的话,函数的匿名性将使生产错误消息难以产生。
你会看到的最好的事情是:
stdin: some error!
stdin: in function 'unknown'
stdin: in function 'unknown'
因此,他们做到了这一点,当解析Lua代码时,它会记录一些 debug 信息,以使生活更轻松。要从Lua本身访问此信息,请提供debug library 要非常小心此库中的功能。
使用此库时应小心谨慎。此处提供的功能应专门用于调试和类似任务,例如分析。请抵制将它们用作通常的编程工具的诱惑:它们可能非常慢。此外,其中一些函数违反了一些关于Lua 代码的假设(例如,函数本地的变量无法从外部访问或者用户数据元表不能通过Lua代码更改)因此可能会损害其他安全性代码。
要达到理想的效果,您必须使用debug.getinfo
功能;一个例子:
x = function()
print("test!")
print(debug.getinfo(1, "n").name)
end
x() -- prints "test!" followed by "x"
不幸的是,直接在函数上运行的debug.getinfo形式没有填充name
参数(debug.getinfo(x, "n").name == nil
),上面的版本要求你运行该函数。
这似乎无望!
... 除非 ..
..你 真的 违反了规则
debug.sethook
函数允许您在某些事件中中断运行的Lua代码,甚至在事情发生时更改内容。这与coroutines相结合,可以让你做一些有趣的hacky东西
以下是debug.getfuncname
的实现:
function debug.getfuncname(f)
--[[If name found, returns
name source line
If name not found, returns
nil source line
If error, returns
nil nil error
]]
if type(f) == "function" then
local info = debug.getinfo(f, "S")
if not info or not info.what then
return nil, nil, "Invalid function"
elseif info.what == "C" then
-- cannot be called on C functions, as they would execute!
return nil, nil, "C function"
end
--[[Deep magic, look away!]]
local co = coroutine.create(f)
local name, source, linedefined
debug.sethook(co, function(event, line)
local info = debug.getinfo(2, "Sn")
name = info.namewhat ~= "" and info.name or nil
source, linedefined = info.short_src, info.linedefined
coroutine.yield() -- prevent function from executing code
end, "c")
coroutine.resume(co)
return name, source, linedefined
end
return nil, nil, "Not a function"
end
使用示例:
function test()
print("If this prints, stuff went really wrong!")
end
print("Name = ", debug.getfuncname(test))
此功能不太可靠 - 它有时有效,而其他功能则无效。调试库非常敏感,所以可以预料到。
请注意,您应该从不将其用于实际的发布代码!仅用于调试!
仍然可以接受的最极端情况是记录已发布软件的错误,以帮助开发人员解决问题。 任何重要代码都不应该依赖于调试库中的函数。
答案 1 :(得分:1)
该功能没有任何名称。如果需要,可以将其分配给命名变量:
theFunction = t[1]
-- Call it:
theFunction()
如果您想要将命名函数存储到表中,请事先定义它并使用其名称来存储它:
theFunction = function()
print ("rock");
end
table.insert(t, 1, theFunction)
如果这不是您的意思,请提供更多详细信息;例如,您希望如何访问该功能。你的问题有点迷雾。
答案 2 :(得分:0)
事情是table.insert将表视为序列,仅使用数字键。
如果您希望能够将函数调用为t.fun()
,则必须将该表用作关联数组,因此使用字符串作为键。 (BTW除了nil或NaN之外的任何类型都可以作为关键)
t={}
t['MyFun']=function print'foo' end
t.myFun() -- uses syntactic sugar for string keys that are valid identifiers.
您可能还会注意到函数是通过引用传递的。因此,所有函数实际上都是匿名的,并且只是作为值存储到某个键或变量。
答案 3 :(得分:0)
您可以将名称存储在单独的表格中。
functions = {}
functionNames = {}
function addFunction(f, name)
table.insert(functions, f)
functionNames[name] = f
end
要获取该功能,您可以使用索引。获得该功能后,您可以从function_names获取其名称:
f = functions[3]
name = functionNames[f]
祝你好运!