问题描述
我尝试了此示例代码以查看其是否有效
--This example is from Programming in Lua Second Edition
function values (t)
local i = 0
return function ()
i = i + 1
return t[i]
end
end
t = {10,20,30}
iter = values(t)
while true do
local element = iter()
-- calls the iterator
if element == nil then
break
end
print(element) --> 10,30
end
我决定稍作更改,我认为代码将获得相同的结果,但我认为我错了
--This example is from Programming in Lua Second Edition
function values (t)
local i = 0
return function ()
i = i + 1
return t[i]
end
end
t = {10,30}
while true do
local element = values(t)()
-- calls the iterator
if element == nil then
break
end
print(element) --> This will print 10 forever if I don't stop the IDE
end
iter
为什么那么重要?
解决方法
当您执行local element = values(t)()
时,实际上是每次循环运行时都创建一个迭代器函数。记下您的values
函数,看它有一个名为i
的局部变量。每次运行此函数时,都会初始化局部变量并将其发送到处理迭代的内部函数。原始示例非常好,但是,如果您想练习局部变量和全局变量,则可以将local i
更改为全局变量i
或其他名称,然后将其移到函数外,这样每次运行迭代函数都不会被调用(您可以将其保持在本地,因此作用域将限于当前文件)。但是,完全不建议这样做,因为您的值可能会在一段时间后被另一个函数或文件重用,这也会使您每次运行只能进行一次完整的迭代(除非您将该值重新设置为零,然后再尝试进行迭代)。 )
local i = 0 -- Notice that the variable is taken out of the function.
-- With your example,the problem was that this variable was set to 0 for every
-- time you called the function.
function values (t)
return function ()
i = i + 1
return t[i]
end
end
t = {10,20,30}
while true do
local element = values(t)()
-- calls the iterator
if element == nil then
break
end
print(element) --> This will print 10 forever if I don't stop the IDE
end
还要牢记性能,因为每次迭代示例时,垃圾回收都会创建,调用并销毁一个函数。这就是为什么原始示例仅创建一次迭代器函数,然后多次调用它,而您的示例在每次循环时都创建迭代器函数的原因。
如果您要做的只是遍历表中的元素,那么lua已经具有通用的for循环(对),请检查here和here。您的情况下的示例(这也会大大缩短您的代码):
local t = {10,30}
-- We don't need key in this case,but if you do,replace _ with k or
-- any other variable name you want.
for _,element in pairs(t) do
print(element)
end