为什么这不是一个有效的表迭代器?
2015-8-10 13:52:18
收藏:0
阅读:82
评论:2
我在Lua课程中看到了这个例子:
function fromto(a, b)
return
function(state, seed)
if (seed >= state) then return nil
else return seed+1 end
end, b, a-1
end
它返回从a到b(包括a和b)连续的整数。因此,我尝试通过编写以下表迭代器来应用相同的逻辑:
function values(t) -- t是一个表
return
function(state, seed)
return state[seed+1]
end, t, 0
end
它正确返回第一个值,但随后抛出错误,指出我不能在一个字符串值( seed )上进行算术运算。但是,接收到的值 seed 不是整数值 0 吗?发生了什么?
由于第一个示例中没有递增过程(例如 a = a + 1 ),我认为Lua可能在后台处理它......但如果它不这样做,那么可能就是我困惑的原因。
点赞
用户2546626
你可以使用闭包来使用另一种迭代器形式:
local function values(t)
local i = 0
return function()
i = i + 1
return t[i]
end
end
for x in values({1, 2, 3}) do
print(x)
end
1 2 3
一个迭代器会一直执行直到返回nil。 一个无效的table字段(位于最后一个之后)始终为 nil,所以只需要继续执行即可。
在你的示例中使用传递计数器值的表单在更新最后计数器值方面使用返回值,通常不会被使用。你使用table条目字符串更新了seed,所以下一次执行会失败。
顺便提一下:你的values函数与ipairs相同。
2015-08-09 20:14:18
评论区的留言会收到邮件通知哦~
推荐文章
- 如何将两个不同的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中获取用户配置主目录的跨平台方法
seed是你迭代函数的第二个参数而不是一个好的名称,它实际上是控制变量。当你从values返回 0 时,你才 "种下" 它,但是在循环期间它的值会改变:它将成为迭代函数返回的第一个值。你从迭代器函数返回了一个字符串 (
return state[seed+1]),因此下次调用迭代器函数时,它会被传递该字符串。你试图对其进行数学计算,然后就...崩溃了。通用的
for循环需要三个参数:一个迭代器函数、一个不变的状态和一个初始的控制值。迭代器使用状态和控制值进行调用。迭代器然后 返回 下一个控制值,或者返回nil表示迭代结束。t = {"foo","bar","zip","zap"} local function iteratorFunction (state, index) index = index + 1 local val = state[index] if val == nil then return nil end return index, val end for k, v in iteratorFunction, t, 0 do print(k,v) end因此,对
iteratorFunction的第一次调用接收到的是t和0作为参数。对iteratorFunction的 下一次 调用会得到t和 _从iteratorFunction返回的第一个值_,以此类推。当你编写一个 "generate" 函数像
values一样,你仅仅是返回了通用for循环所需的三个初始值,这样在使用该迭代器时你的代码更简洁:function values(t) local function iteratorFunction (state, index) index = index + 1 local val = state[index] if val == nil then return nil end return index, val end return iteratorFunction, t, 0 -- 和上面循环中使用的三个值相同 end for k, v in values(t) do print(k,v) end通用
for循环仅需要迭代器函数作为必需参数。不变的状态和控制变量可以为nil,如果你的迭代逻辑在一个闭包中完成,你可能会这么做:function values(t) local index = 0 -- 我们的迭代器函数是一个绑定到 `index` 和 `t` 的闭包 local function iteratorFunction() index = index + 1 local val = t[index] if val == nil then return nil end return index, val end return iteratorFunction, t, 0 -- 和上面循环中使用的三个值相同 end for k, v in values(t) do print(k,v) end如果你将
return index, val更改为return val,values(t)现在将只迭代t中的值。我们之前无法这样做,因为我们需要返回一个控制变量供下次循环迭代使用。但是有了闭包,我们可以通过一个绑定到闭包的变量(即 "upvalue")来维护控制变量。