Lua在递归函数中声明局部变量。
2013-10-3 10:42:59
收藏:0
阅读:91
评论:2
我刚开始学习编程并选择使用Lua编写处理XML配置文件的脚本。
我使用LuaXML(C绑定版本)加载XML文件,它将其映射到一个嵌套表中。
当我尝试编写一个函数以查找xmltable中标签的所有匹配项时,我的问题出现了。匹配项被插入由该函数返回的表中。我的问题在于这个表变量的声明,它必须在函数局部范围内。
首先我尝试了:
local result = result or {}
但这会在每个递归中声明变量。
最后我想到了这个解决方案,虽然它能够工作,但对我来说似乎太复杂了:
function findall_wrapper(xmltable, tag)
local results = {}
function findall(xmltable, tag)
if xml.TAG == tag then table.insert (results, xmltable) end
for k, v in pairs(xmltable) do
if (type(v) == "table") then findall(v, tag) end
end
end
findall(xmltable, tag)
return results
end
我如何以更好、更简洁的方式解决这个问题?为什么 local result = result or {} 在每个递归中声明变量?
如果我的问题的答案太显然,请原谅,因为我刚开始学习编程。
点赞
用户2279620
如果你的意思是你不想使用一个包装器函数,那么我认为你已经做得非常接近了。这是你的预期吗?
function findall(xmltable, tag, results)
local results = results or {}
if xmltable[xml.TAG] == tag then table.insert(results, xmltable) end
for k, v in pairs(xmltable) do
if type(v) == "table" then findall(v, tag, results) end
end
return results
end
2013-05-07 16:12:14
评论区的留言会收到邮件通知哦~
推荐文章
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
实际上,我认为你提出了一个不错和优雅的解决方案。你所做的是利用Lua中的函数是闭包的特性,这在编写需要同时运行时构建数据结构的递归函数时可以是非常有用的技术。要使它完美,你只需要在
function findall_wrapper内部的function findall前面添加local关键字,那么你的辅助函数将是局部的,不会污染全局命名空间。稍作阐述:
有两种不同类型的函数,简单递归函数和复杂递归函数。所有递归函数都可以按照以下方式实现:
function sum_list(l) if #l == 0 then return 0 else local e = table.remove(l) return e + sum_list(l) end end print(sum_list({1,2,3,4})) > 10这里调用栈用于存储中间结果,这可以在返回中具有非常大的堆栈,深递归或多次调用函数。
更好的方法称为尾递归:
function sum_list(l, a) if #l == 0 then return a else local e = table.remove(l) return sum_list(l, a + e) end end print(sum_list({1,2,3,4}, 0)) > 10在这个例子中,累加器在调用中被传递,所以调用栈不再用于存储,如果实现支持它,它可以将其转换为迭代。不幸的是,并非所有递归函数都是尾递归的。在这种情况下累加器的问题是人们必须将其实例化为零,否则会给出错误的结果。
解决方法就是你所做的:
function sum_list(l) local function sum_list_helper(l, a) if #l == 0 then return a else local e = table.remove(l) return sum_list_helper(l, a + e) end end return sum_list_helper(l, 0) end这里创建了一个局部函数,然后使用正确的实例化值进行调用。