2012-05-18 216 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代码,虽然它可能不是你的原意。