在Lua中,是否有一个给定函数的函数,它将其名称作为字符串返回?

时间:2011-10-25 08:42:37

标签: lua

很抱歉,如果这太明显了,但我是lua的新手,我在参考资料中找不到它。

在Lua中是否有一个NAME_OF_FUNCTION函数,给定一个函数给我一个名字,以便我可以用它索引一个表?我想要的原因是我想做这样的事情:

local M = {}

local function export(...)
   for x in ...
     M[NAME_OF_FUNCTION(x)] = x
   end
end

local function fun1(...)
...
end

local function fun2(...)
...
end

.
.
.

export(fun1, fun2, ...)

return M

4 个答案:

答案 0 :(得分:5)

根本没有这样的功能。我想没有这样的功能,因为功能是一等公民。所以函数只是一个像变量一样引用的值。因此NAME_OF_FUNCTION函数不会非常有用,因为同一个函数可以有许多指向它的变量,或者没有。

您可以通过循环遍历表(任意或_G)来模拟全局函数或表中的函数,检查值是否等于x。如果是这样,你找到了函数名。

a=function() print"fun a" end
b=function() print"fun b" end
t={
   a=a,
   c=b
}
function NameOfFunctionIn(fun,t) --returns the name of a function pointed to by fun in table t
   for k,v in pairs(t) do
       if v==fun then return k end
   end
end
print(NameOfFunctionIn(a,t)) -- prints a, in t
print(NameOfFunctionIn(b,t)) -- prints c
print(NameOfFunctionIn(b,_G)) -- prints b, because b in the global table is b. Kind of a NOOP here really.

另一种方法是将函数包装在表中,并设置一个调用函数的元表设置,如下所示:

fun1={
    fun=function(self,...)
        print("Hello from "..self.name)
        print("Arguments received:")
        for k,v in pairs{...} do print(k,v) end
    end,
    name="fun1"
}
fun_mt={
    __call=function(t,...)
        t.fun(t,...)
    end,
    __tostring=function(t)
        return t.name
    end
}
setmetatable(fun1,fun_mt)
fun1('foo')
print(fun1) -- or print(tostring(fun1))

由于metatable查找,这将比使用裸函数慢一点。并且它不会阻止任何人更改状态中函数的名称,更改包含它的表中的函数名称,更改函数等等,因此它不是防篡改。您也可以通过像fun1.fun这样的索引来剥离表,如果将它作为模块导出可能会很好,但是你可以放弃命名和其他可以放入元数据的技巧。

答案 1 :(得分:1)

从技术上讲,这是可能的,这是export()函数的一个实现:

function export(...)
        local env = getfenv(2);
        local funcs = {...};
        for i=1, select("#", ...) do
                local func = funcs[i];
                for local_index = 1, math.huge do
                        local local_name, local_value = debug.getlocal(2, local_index);
                        if not local_name then
                                break;
                        end
                        if local_value == func then
                                env[local_name] = local_value;
                                break;
                        end
                end
        end
        return env;
end

它使用debug API,需要对Lua 5.2进行一些更改,最后我不一定认可它是编写模块的好方法,我只是在字面上回答这个问题。

答案 2 :(得分:0)

试试这个:

http://pgl.yoyo.org/luai/i/tostring

tostring(x)应该有希望成为你想要的东西

答案 3 :(得分:0)

如果我没有错(我可能会,因为我实际上从未在Lua中编程,只读过一堆文章和文章),内部已经有一个包含函数名称的表(如locals和{ Python中的{1}},因此您应该能够执行反向查找以查看哪个键与函数引用匹配。

无论如何,只是推测。

但事实是,查看代码,您已经知道了函数的名称,因此您可以自由地构建表。如果你想减少错误,那么使用函数的名称来获取函数引用(使用globals或类似的东西)比使用其他方法更容易。