我无法绕过这个工作的Lua snipplet。
此:
t = {'a', 'b', 'c'}
for k, v in next, t, nil do
print(k, v)
end
返回:
1 a
2 b
3 c
有人可以解释,
next
如何获得t
作为参数?t
to
for
参数的方式。{li}
nil
并将其视为有效步骤?答案 0 :(得分:3)
要扩展其他答案:
“循环”通用中涉及的值的更具描述性的命名'如下:
for k, v1, v2, … in f_step, state, k0 do … end
它会像
一样循环k,v1,v2,…=f_step(state,k0) ; if k==nil then break end ; k0=k ; --(…for body here…)
k,v1,v2,…=f_step(state,k0) ; if k==nil then break end ; k0=k ; --(…for body here…)
k,v1,v2,…=f_step(state,k0) ; if k==nil then break end ; k0=k ; --(…for body here…)
…
和f_step可以任意方式自由修改state
(尽管pairs
/ next
不这样做,而另一个例子是{{1} }甚至完全忽略string.gmatch
和 state
并将所有不同的状态保持在一个闭包中(想想'函数'如果你不知道那个(而是)。)
现在,k
所做的基本上只是
pairs
和共同的
function pairs( t )
-- (__pairs logic goes here, omitted for brevity)
return next, t, nil
end
基本上扩展到
for k, v in pairs( t ) do … end
(除非for k, v in next, t, nil do … end
具有t
的元表。)
现在有两个原因可以明确地写出__pairs
而不是next, t, nil
- 来混淆那些对此还不了解的人,或者避免触发{{1 }}。 (为了避免触发pairs
/ __pairs
,您有__index
/ __newindex
,为了避免rawget
,您明确地写了rawset
。或许您定义__pairs
并使用它......)
答案 1 :(得分:1)
所有积分都会转到Egor,以便在评论中回答。
像
这样的for语句for var_1, ···, var_n in explist do block end
等同于代码:
do local f, s, var = explist while true do local var_1, ···, var_n = f(s, var) if var_1 == nil then break end var = var_1 block end end
因此,原始语句转换为无限while
循环,继续使用初始参数next()
调用next(t, nil)
,并在每次迭代中将第二个参数替换为下一个索引。 t
表。最后next(t, index_n)
返回nil
时,循环中断。
在我看来,这是一种非常强大的遍历表的方法,因为next()
可以被几乎任何完全控制迭代的函数所取代。哇。