为什么这段代码片段无法编译,而`print(square(3,0))`可以?

为什么这段代码片段无法编译,而print(square(3,0))可以?

function square(iteratorMaxCount,currentNumber)

   if currentNumber<iteratorMaxCount
   then
      currentNumber = currentNumber+1
      return currentNumber, currentNumber*currentNumber
   end

end

print(square(3,0))

for i,n in square(3,0)
do
   print(i,n)
end

编译器报错:

> $lua main.lua 1   1 lua: main.lua:13: attempt to call a number value
> stack traceback:  main.lua:13: in main chunk  [C]: in
点赞
用户7396148
用户7396148

for i,n in square(3,0) 等同于 for i,n in 1,1 ,这意味着你正在尝试调用 1,它不是一个函数,导致错误 attempt to call a number value

在 for 循环定义中,in 后面表达式列表中的第一个值需要是一个函数,比如处理表格或数组时使用的 pairsipairs。如果你使用某些自定义的迭代器,比如代码中的 square,你需要创建一个定义迭代器并存储限制为 upvalue 的匿名函数。这个函数叫做迭代器工厂。

function square(iteratorMaxCount,currentNumber)
    return function()
        if currentNumber<iteratorMaxCount then
            currentNumber = currentNumber+1
            return currentNumber, currentNumber*currentNumber
        end
    end
end

print(square(3,0)())
print(square(3,0))

for i,n in square(3,0) do
    print(i,n)
end

另外,你可以在 for 循环表达式列表中定义 2 个值,不变状态和控制变量,通过将初始状态传递给函数。

for i,n in square,3,0 do
    print(i,n)
end

建议阅读:

Programming in Lua: 7.2 – The Semantics of the Generic for

相关主题:

Programming in Lua: 4.3.5 – Generic for

Programming in Lua: 7.1 – Iterators and Closures

Programming in Lua: 7.3 – Stateless Iterators

2020-09-23 17:34:55