2012-11-03 19 views
2

確定這裏是一個基本的for循環Lua - 爲什麼循環限制不是動態計算的?

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循環會打破......

肯定會更有意義嗎? 還是有什麼特別的原因,爲什麼不是這樣?

回答

7

的主要原因數值for循環限制只計算一次是肯定的性能。

使用當前行爲,可以在for循環限制中放置任意複雜表達式,而不會出現性能損失(包括函數調用)。例如:

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

上面的代碼將是非常緩慢的,如果computeEndLoopcomputeStep需要在每次迭代被調用。

如果標準Lua解釋器和最顯着的LuaJIT與其他腳本語言相比速度如此之快,那是因爲許多Lua功能的設計都考慮到了性能。


在罕見的情況下,單一的評價行爲是不可取的,它很容易使用while endrepeat until一個通用的循環替換for循環。

local prod = 1 
local i = computeStartLoop() 
while i <= computeEndLoop() do 
    prod = prod * i 
    i = i + computeStep() 
end 
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) 
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