2016-03-02 19 views
8

我發現一個奇怪的一段代碼的Lua文檔中:Lua - 本地需要的eveytime是否分配了一個局部變量?

function trim8(s) 
    local i1,i2 = find(s,'^%s*') 
    if i2 >= i1 then s = sub(s,i2+1) end 
    local i1,i2 = find(s,'%s*$') 
    if i2 >= i1 then s = sub(s,1,i1-1) end 
    return s 
end 

爲什麼再次使用i1i2local?他們不是已經在局部變量中聲明瞭嗎?每次要分配關鍵字時,是否必須重複使用local關鍵字?

回答

7

不,不需要一遍又一遍地使用local。由於第一行本身,變量i1i2將在功能範圍內爲local

雖然不應該這樣做,但一遍又一遍地定義相同的變量沒有任何問題。它只會將新的堆疊位置分配給較新的位置,並對較舊的位置進行遮蔽。

下面是一個簡單的函數中的指令輸出:

function t() 
    local i = 2 
    local i = 3 
end 
t() 
function <temp.lua:1,4> (3 instructions, 12 bytes at 00658990) 
0 params, 2 slots, 0 upvalues, 2 locals, 2 constants, 0 functions 
     1  [2]  LOADK   0 -1 ; 2 
     2  [3]  LOADK   1 -2 ; 3 
     3  [4]  RETURN   0 1 

以及更新所述第二local i = 3只是i = 3

function t() 
    local i = 2 
    i = 3 
end 
t() 
function <temp.lua:1,4> (3 instructions, 12 bytes at 00478990) 
0 params, 2 slots, 0 upvalues, 1 local, 2 constants, 0 functions 
     1  [2]  LOADK   0 -1 ; 2 
     2  [3]  LOADK   0 -2 ; 3 
     3  [4]  RETURN   0 1 

通知在所述第二差指令。


除此之外,該功能是相當低效的。您可以改用以下內容:

function Trim(sInput) 
    return sInput:match "^%s*(.-)%s*$" 
end 
+2

堆棧位置(局部變量)不受垃圾收集。存儲在陰影局部變量中的值仍被視爲可訪問。 –

+0

@EgorSkriptunoff你有一個規範參考或是基於觀察? (我知道我在編寫調試器時在標準實現中看到了影子本地人。)但是,編譯器是不是可以自由地優化堆棧使用? –

+0

@TomBlodget - IMO,對於典型的Lua程序來說堆棧優化是非常不可能的。 –

5

從技術上講,在第二聲明使用local與否是不等價的。使用第二個local將聲明另一個變量。

但是在你的示例代碼中,它們基本上是一樣的。檢查這些簡單的代碼:

local a = 0 
local a = 1 

local a = 0 
a = 1 

使用luac -p -l輸出以下結果:

0+ params, 2 slots, 0 upvalues, 2 locals, 2 constants, 0 functions 
    1 [1] LOADK  0 -1 ; 0 
    2 [2] LOADK  1 -2 ; 1 
    3 [2] RETURN  0 1 

0+ params, 2 slots, 0 upvalues, 1 local, 2 constants, 0 functions 
    1 [1] LOADK  0 -1 ; 0 
    2 [2] LOADK  0 -2 ; 1 
    3 [2] RETURN  0 1 
+0

嘿,我只是用'luac -l'輸出= P – hjpotter92

+0

來更新我的回覆謝謝你的幫助。那麼當您聲明'a'兩次時,標識符'a'引用的變量是什麼?第二個被宣佈? – Virus721

+0

@ Virus721在聲明第二個聲明的整個語句之後,它將是第二個聲明,例如'local a = 0;本地a = a + 1'會將值0 + 1賦值給第二個變量。 –