2012-05-18 265 views
3

我知道還有其他類似的主題,但無法找到我的問題的直接答案。lua變量範圍

假設你有一個函數,例如:

function aFunction() 
    local aLuaTable = {} 
    if (something) then 
    aLuaTable = {} 
    end 
end 

對於aLuaTable變量if語句裏,它仍然是地方吧?基本上我問的是,如果我第一次將變量定義爲本地變量,然後我一次又一次地使用變量,它會在程序剩餘時間內保持局部變化,這是如何工作的?

此外,我讀這個定義爲lua全局變量:

任何變量不是在一個定義的塊被認爲是在全局範圍內。 全局範圍內的任何內容均可由所有內部範圍訪問。

這是什麼意思是不是在一個定義的塊?我的理解是,如果我「隨便聲明」一個變量它將永遠是全球性的是不正確的?

對不起,如果問題太簡單了,但來自Java和objective-c,lua對我來說很奇怪。

+0

沒有很多XP用LUA的地獄,但據我所知,該變量將在該函數內部範圍 - 這將是超出範圍的功能之外。任何在函數體(定義塊)之外聲明的變量被認爲是在全局範圍內,並且可以從該lua腳本中的任何地方訪問 – Charleh

回答

8

「任何不在定義塊中的變量都被認爲是在全局範圍內。」

這簡直是錯誤的,所以你的困惑是可以理解的。看起來你是從用戶wiki中獲得的。我剛剛更新了帶有更正信息的頁面:

任何未定義爲local的變量都是全局變量。

我的理解是,如果我在任何地方「聲明」一個變量,它會永遠是全球性的

如果你不把它定義爲local,這將是全球性的。但是,如果您創建了一個名稱相同的local,則它將優先於全局(即,嘗試解析變量名稱時,首先是Lua「看到」當地人)。看到這篇文章底部的例子。

如果我定義一個變量作爲當地的第一次,然後我一次又一次地使用任意數量的時候,它會保持當地傳爲計劃的餘生,如何做這項工作到底是什麼?

當你的代碼被編譯,Lua的跟蹤用戶定義的任何局部變量和知道哪些是在給定的範圍內都有效。每當你讀/寫一個變量時,如果這個名稱的範圍內存在一個局部範圍,就使用它。如果沒有,則將讀/寫轉換(在編譯時)爲讀/寫表(通過表_ENV)。

local x = 10 -- stored in a VM register (a C array) 
y = 20  -- translated to _ENV["y"] = 20 

x = 20  -- writes to the VM register associated with x 
y = 30  -- translated to _ENV["y"] = 30 

print(x)  -- reads from the VM register 
print(y)  -- translated to print(_ENV["y"]) 

當地人在詞彙範圍內。其他一切都在_ENV

x = 999 

do -- create a new scope 
    local x = 2 
    print(x)  -- uses the local x, so we print 2 
    x = 3   -- writing to the same local 
    print(_ENV.x) -- explicitly reference the global x our local x is hiding 
end 

print(x) -- 999 
+2

只需注意'_ENV'只是Lua 5.2。在Lua 5.1中(和之前),全局變量存儲在'_G'中(實際上它比這更復雜一些,你可以改變函數的環境等等)。 –

+2

我考慮過提及_G(這是5.1中的全局狀態和5.2中_ENV的默認值),但我認爲這隻會讓人困惑。 5.2是最新的版本,所以我去了_ENV。所有有關作用域的信息都是相同的,只是在5.1中,_ENV引用是_G引用。 – Mud

2

對於if語句中的aLuaTable變量,它仍然是本地的權利?

我不明白你在這裏感到困惑;該規則與Java的規則完全相同。該變量仍在範圍內,因此它繼續存在。

A local變量等同於在Java中定義「堆棧」變量。該變量存在於定義它的塊範圍內,並在該塊結束時停止存在。

考慮這個Java代碼:

public static void main() 
{ 
    if(...) 
    { 
    int aVar = 5; //aVar exists. 
    if(...) 
    { 
     aVar = 10; //aVar continues to exist. 
    } 
    } 

    aVar = 20; //compile error: aVar stopped existing at the } 
} 

「全局」 簡直就是當地任何變量名。考慮相當於Lua代碼上面:

function MyFuncName() 
    if(...) then 
    local aVar = 5 --aVar exists and is a local variable. 

    if(...) then 
     aVar = 10 --Since the most recent declaration of the symbol `aVar` in scope 
       --is a `local`, this use of `aVar` refers to the `local` defined above. 
    end 
    end 

    aVar = 20 --The previous `local aVar` is *not in scope*. That scope ended with 
      --the above `end`. Therefore, this `aVar` refers to the *global* aVar. 
end 

什麼用Java將是一個編譯錯誤是完全有效的Lua代碼,雖然它可能不是你的原意。