我在玩下面的代码时感到困惑。
function square(iteratorMaxCount,currentNumber)
if currentNumber<iteratorMaxCount
then
currentNumber = currentNumber+1
return currentNumber, currentNumber*currentNumber
end
end
for i,n in square,3,0
do
print(i,n)
end
我困惑的一点是:for i,n in square,3,0
究竟是什么?我在终端中尝试了这个,结果出现了以下错误。
stdin:2: attempt to compare number with nil
stack traceback:
stdin:2: in function 'for iterator'
stdin:1: in main chunk
[C]: in ?
如有任何意见,我们将不胜感激。
编辑:我再试了一次。这一次,我在"for I,n in square,3,0"之间放置了空格,结果很好。
这是Lua的通用for
循环的语法。
引用参考手册:
等语句的A
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
注意以下内容:
- explist只评估一次。它的结果是迭代器函数、状态和第一个迭代器变量的初始值
- f、 s和var是不可见的变量。此处的名称仅供解释
原文中几乎没有其他注释,但我们现在可以跳过它们。请参阅参考手册了解完整版本及所有注释。
让我们首先考虑pairs
的基本用法:
for k, v in pairs({5, 6, 7}) do
print(k, v)
end
对pairs
的调用返回一个迭代器和泛型的状态。第三个值自动指定为nil
。我们可以在代码中更具描述性,并将上面的示例更改为:
local f, s, var = pairs({5, 6, 7})
for k, v in f, s, var do
print(k, v)
end
请注意,两个样本的行为方式相同。我们可以加强我们的游戏,完全摆脱pairs
:
for k, v in next, {5, 6, 7}, nil do
print(k, v)
end
next
函数接受两个参数:一个表和一个键,然后返回表的下一个成员的键和值。这意味着上述样品也是之前样品的等价物。
最终有三件事预计会成为for k,v in <HERE> do
:
- 一个迭代器-函数,每次迭代都会调用该函数为
for <HERE> in
中声明的变量赋值 - 状态-在每次迭代中传递给迭代器的值
- 初始值-在循环的第一次迭代中作为第二个参数传递给迭代器的值
像pairs
、ipairs
或gmatch
这样的函数只是返回一些预期的东西,如上面的pairs
示例所示。
在您的情况下,迭代器是square
,state为3
,<strong]初始值>则为0
。这意味着i, n
的值将被分配为:i, n = square(3, i or 0)
(第一次迭代中的0
,然后是上一次迭代中i
的值(。
Lua中的编程也有一个很好的章节:PIL-4.3.5-Generic for。我强烈鼓励你阅读它。事实上,我强烈建议你阅读整个PIL,因为它是用Lua编程的一个很好的起点。