lua中函数的唯一Id
我在游戏引擎中使用Lua。我经常需要在给定的时间间隔内做一些事情,而蛮力的方法是为我需要做的每件事情创建一个变量来跟踪我上次做的事情。这让我的代码中充斥着我不想看到的变量,因为它们更面向工作,而不是面向意图。所以我有一个想法,做一个函数,可以自动为我做这件事。我只需要提供一个间隔,以及一个我定义的内联函数,它包含了我在这个间隔内需要做的事情。(在我的示例中,我使用“类”,因此我还定义了对象) 当然,我仍然需要生成最后一个更新变量来跟踪每个变量,但是如果我可以在这个函数中屏蔽这些变量,那么我必须编写的代码就变得更简单了。因此,在传入obj时,我需要为调用函数时的每个语句创建一个唯一的变量。我想我可以使用回调函数的字符串名,但每次都不一样,因为它是一个匿名函数匿名函数是否可以生成唯一的变量名,以便在使用此系统时不必跟踪任何内容?因为同一个对象的两个匿名函数都不是同一个,所以函数本身的某种散列可能是相同的?但不确定您是否可以在Lua中实现这一点lua中函数的唯一Id,lua,Lua,我在游戏引擎中使用Lua。我经常需要在给定的时间间隔内做一些事情,而蛮力的方法是为我需要做的每件事情创建一个变量来跟踪我上次做的事情。这让我的代码中充斥着我不想看到的变量,因为它们更面向工作,而不是面向意图。所以我有一个想法,做一个函数,可以自动为我做这件事。我只需要提供一个间隔,以及一个我定义的内联函数,它包含了我在这个间隔内需要做的事情。(在我的示例中,我使用“类”,因此我还定义了对象) 当然,我仍然需要生成最后一个更新变量来跟踪每个变量,但是如果我可以在这个函数中屏蔽这些变量,那么我必须编
function DoEvery(interval, obj, method)
-- somehow I need a way to uniquely ID the passed in method so I can make a variable on the passed in obj that tracks it's last time called
print(tostring(method)) -- this gives a new address each cycle so that won't work
end
Script = {}
function Script:Create()
local obj = {}
obj.name = "Mike"
for k,v in pairs(Script) do
obj[k] = v
end
return obj
end
function Script:Update()
DoEvery(250, self, function(self)
print(self.name)
end)
end
local script = Script:Create()
script:Update()
script:Update()
script:Update()
此解决方案需要访问
debug
库并编译源代码,而无需剥离调试信息(如果您的lua文件存储为预编译字节码)
定义命名的本地函数
function print\u name(self)print(self.name)end
外部Script:Update()
并使用DoEvery(250,self,print\u name)
作为Script:Update()
body。因此,每次调用script:Update()
时,在DoEvery()
函数中都会有相同的method
参数。您可以使用tostring(method)
或method
本身作为script
对象内的键来存储上次访问时间。我希望函数是内联的,以便在读取代码时,您不必去其他地方查看发生了什么。我希望它有点像一个lambda表达式。再添加一个参数-对您的意图的简短描述:DoEvery(250,“print name”,self,function(self)…end)
此字符串参数将用作注释(以简化对代码的理解)作为一把独特的钥匙。我在想,但我觉得这就像手动跟踪我想要避免的独特性一样。这意味着我必须知道在对DoEvery()的任何其他不同调用中不要使用“print name”,这将导致手动错误。如果我要走这条路,我只会给它一个数字,这将作为字典的键,其中的值是最后一次更新。我只是不想手动跟踪,因为它很容易出错。今晚我会在我的游戏引擎中检查它。如果它在那里工作,这是辉煌的,我会接受它作为答案。游戏引擎通常没有访问调试库。游戏引擎实际上支持它!这将工作完美谢谢!使用此库时应小心。此处提供的函数应专门用于调试和类似任务,如分析。请抵制诱惑,将其用作常用编程工具:它们可能非常慢因此,如果函数是匿名函数最常用的情况之一,那么它实际上不会唯一地标识函数:在绑定upvalue之后返回它们。所以要小心。它只是根据函数
关键字的位置返回一个字符串,而不考虑这些函数在内存中的数量。我建议您改为使用tostring(method)
,这将为您提供lua内部使用的标识符,因此当函数被“复制”/“工厂返回”等时,它应该更加健壮。它也比滥用调试库快得多
function DoEvery(interval, obj, method)
local info = debug.getinfo(method, "S")
local id = info.linedefined..info.source
print(id)
-- "id" consists of line number and file name
-- where "method" function was defined
-- so it is unique
-- (unless you write two anonymous functions on the same line)
end