Lua - 为什么循环限制不是动态计算的?

时间:2012-11-03 23:40:09

标签: for-loop lua iteration

好的,这是一个基本的循环

local a = {"first","second","third","fourth"}
for i=1,#a do 
    print(i.."th iteration")
    a = {"first"}
end 

现在,循环执行所有4次迭代。

不应该计算for-loop-limit吗?如果它是动态计算的,那么#a在第一次迭代结束时将为1,而for循环将会中断....

肯定会更有意义吗? 或者,为什么不是这种情况有什么特别的原因?

3 个答案:

答案 0 :(得分:7)

数值for循环限制的主要原因只计算一次,这绝对是性能的。

使用当前行为,您可以在for循环限制中放置任意复杂表达式,而不会影响性能,包括函数调用。例如:

local prod = 1
for i = computeStartLoop(), computeEndLoop(), computeStep() do
  prod = prod * i
end

如果在每次迭代时需要调用computeEndLoopcomputeStep,上面的代码会非常慢。

如果标准的Lua解释器和最着名的LuaJIT与其他脚本语言相比如此之快,那是因为许多Lua功能在设计时都考虑了性能。


在极少数情况下,单个评估行为是不合需要的,使用forwhile end很容易用通用循环替换repeat until循环。

local prod = 1
local i = computeStartLoop()
while i <= computeEndLoop() do
  prod = prod * i
  i = i + computeStep()
end

答案 1 :(得分:1)

在for循环初始化时计算一次长度。每次循环都不会重新计算 - for循环用于从起始值迭代到结束值。如果你希望在重新分配数组的情况下提前终止'loop',你可以编写自己的循环代码:

local a = {"first", "second", "third", "fourth"}                                                                           

function process_array (fn)                                                                                                
   local inner_fn                                                                                                          
   inner_fn =                                                                                                              
      function (ii)                                                                                                        
         if ii <= #a then                                                                                                  
            fn(ii,a)                                                                                                       
            inner_fn(1 + ii)                                                                                               
         end                                                                                                               
      end                                                                                                                  
   inner_fn(1, a)                                                                                                          
end                                                                                                                        


process_array(function (ii)                                                                                                
                    print(ii.."th iteration: "..a[ii])                                                                     
                    a = {"first"}                                                                                          
                     end) 

答案 2 :(得分:0)

性能是一个很好的答案,但我认为这也使代码更容易理解,更不容易出错。此外,您可以(几乎)确保for循环始终终止。

想想如果你写下来会发生什么:

local a = {"first","second","third","fourth"}
for i=1,#a do 
    print(i.."th iteration")
    if i > 1 then a = {"first"} end
end

您如何理解for i=1,#a?它是一个相等比较(在i==#a时停止)还是不等式比较(在i>=#a时停止)。在每种情况下会得到什么结果?

你应该看到Lua for循环是一个序列的迭代,比如使用(x)range的Python习语:

a = ["first", "second", "third", "fourth"]
for i in range(1,len(a)+1):
    print(str(i) + "th iteration")
    a = ["first"]

如果您想在每次使用while时评估条件:

local a = {"first","second","third","fourth"}
local i = 1
while i <= #a do 
    print(i.."th iteration")
    a = {"first"}
    i = i + 1
end