3

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

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 循环将中断....

那肯定会更有意义吗?或者有什么特别的原因说明为什么不是这样?

4

3 回答 3

7

数值循环限制只计算一次的主要原因for肯定是为了性能。

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

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

computeEndLoop如果并且computeStep需要在每次迭代中调用上述代码,将会非常缓慢。

如果标准 Lua 解释器,尤其是 LuaJIT 与其他脚本语言相比如此之快,那是因为许多 Lua 特性在设计时就考虑到了性能。


在不希望单个评估行为的极少数情况下,使用or将for循环替换为通用循环很容易。while endrepeat until

local prod = 1
local i = computeStartLoop()
while i <= computeEndLoop() do
  prod = prod * i
  i = i + computeStep()
end
于 2012-11-04T06:28:49.717 回答
1

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

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) 
于 2012-11-04T00:54:41.327 回答
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)。在每种情况下会产生什么结果?

您应该将 Luafor循环视为对序列的迭代,例如 Python 习惯用法 using (x)range

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
于 2012-11-05T17:21:16.467 回答