如何在Lua中检测闭包以避免string.dump序列化失败?
不用Debug接口检测Lua函数是否为闭包的方案
你不想依赖debug.getupvalue,可以试试这两个可行方案:
方法一:用pcall包裹string.dump做异常捕获
既然string.dump碰到带upvalue的闭包会直接报错,那我们可以用pcall来测试调用是否成功——调用成功就说明是无upvalue的普通函数,失败则是闭包。代码示例:
local function is_plain_function(func) if type(func) ~= "function" then return false end local success = pcall(string.dump, func) return success end
这个方法完全不涉及debug模块,准确性还高,毕竟直接利用了你要调用的string.dump本身的行为来判断,最贴合需求。就算调用成功,也不需要保存返回的字节流,只关注是否成功即可,不会产生额外的性能负担。
方法二:利用函数环境判断(仅Lua5.1及兼容版本可用,可靠性一般)
在Lua5.1中,普通函数的默认环境是全局_G,闭包的环境通常继承自外层函数的环境。但这个方法有明显漏洞:如果手动修改了普通函数的环境,或者闭包的环境被刻意设置为_G,判断结果就会出错。代码仅供参考:
local function is_plain_function(func) if type(func) ~= "function" then return false end local func_env = getfenv(func) return func_env == _G end
这个方法的可靠性远不如方法一,优先推荐使用第一种方案。
内容的提问来源于stack exchange,提问作者Jon Chesterfield
相关产品推荐
相关产品推荐

