Lua(迭代器)
Lua 迭代器基础概念
Lua 迭代器是一种允许遍历集合(如数组、表)元素的机制。迭代器通常由两个部分组成:迭代函数和状态控制变量。每次调用迭代函数会返回集合中的下一个元素。
泛型 for 循环
Lua 提供了泛型 for
循环来简化迭代器的使用。语法如下:
for var1, var2, ..., varN in iterator_function, state, initial_value do -- 循环体end
iterator_function
:迭代函数,每次调用返回下一个值。state
:迭代器的状态(通常是集合本身)。initial_value
:迭代的初始值(通常为 nil)。
无状态迭代器
无状态迭代器不保留任何状态信息,状态完全由外部控制。典型的例子是 ipairs
和 pairs
。
warring:
同:都是能遍历集合(表、数组)
异:ipairs 仅仅遍历值,按照索引升序遍历,索引中断停止遍历。即不能返回 nil,只能返回数字 0,如果遇到 nil 则退出。它只能遍历到集合中出现的第一个不是整数的 key。
pairs 能遍历集合的所有元素。即 pairs 可以遍历集合中所有的 key,并且除了迭代器本身以及遍历表本身还可以返回 nil。
示例:实现类似 ipairs
的迭代器
local function iter(t, i) i = i + 1 if t[i] then return i, t[i] endendfunction my_ipairs(t) return iter, t, 0end-- 使用local arr = {10, 20, 30}for i, v in my_ipairs(arr) do print(i, v)end
有状态迭代器
有状态迭代器将状态封装在闭包或表中,无需外部传递状态。
闭包实现
function my_iter(t) local i = 0 return function() i = i + 1 if t[i] then return i, t[i] end endend-- 使用local arr = {10, 20, 30}for i, v in my_iter(arr) do print(i, v)end
表实现
local iterator = {}iterator.__index = iteratorfunction iterator.new(t) return setmetatable({t = t, i = 0}, iterator)endfunction iterator:__call() self.i = self.i + 1 if self.t[self.i] then return self.i, self.t[self.i] endend-- 使用local arr = {10, 20, 30}for i, v in iterator.new(arr) do print(i, v)end
自定义迭代器
通过实现 __pairs
或 __ipairs
元方法,可以自定义表的迭代行为。
示例:逆序遍历数组
local function reverse_iter(t, i) i = i - 1 if i > 0 then return i, t[i] endendfunction reverse_ipairs(t) return reverse_iter, t, #t + 1end-- 使用local arr = {10, 20, 30}for i, v in reverse_ipairs(arr) do print(i, v)end
协程迭代器
协程可以用于实现复杂的迭代逻辑,尤其是需要跨多次调用维护状态的情况。
示例:遍历二叉树
local function traverse(node) if not node then return end traverse(node.left) coroutine.yield(node.value) traverse(node.right)endfunction tree_iter(root) return coroutine.wrap(function() traverse(root) end)end-- 使用local tree = { value = 2, left = {value = 1}, right = {value = 3}}for v in tree_iter(tree) do print(v) -- 输出 1, 2, 3end
性能优化建议
- 无状态迭代器通常比有状态迭代器更快,因为避免了闭包创建的开销。
- 对于大规模数据,优先使用
ipairs
或pairs
而不是自定义迭代器。 - 协程迭代器虽然灵活,但会有额外的协程调度开销。