lua变量范围

时间:2012-05-18 14:48:11

标签: variables scope lua global-variables

我知道还有其他类似的主题,但找不到我的问题的直接答案。

假设你有一个如下函数:

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

对于if语句中的aLuaTable变量,它仍然是本地的吗?基本上我要问的是,如果我第一次将变量定义为本地变量,然后我会一次又一次地使用它,它会在程序的其余部分保持在本地,这是如何工作的?

另外,我读了Lua全局变量的这个定义:

  

任何不在定义块中的变量都被认为是在全局范围内。   所有内部范围都可以访问全局范围内的任何内容。

不是在一个已定义的块中是什么意思?我的理解是,如果我在任何地方“声明”变量,它将永远是全局的,那是不正确的。

很抱歉,如果问题太简单,但来自Java和objective-c,对我来说,lua非常奇怪。

2 个答案:

答案 0 :(得分:10)

  

“不在定义的块中的任何变量都被认为是在全局范围内。”

这是完全错误的,所以你的困惑是可以理解的。看起来你从用户维基得到了它。我刚刚用更正信息更新了页面:

任何未定义为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

答案 1 :(得分:2)

  

对于if语句中的aLuaTable变量,它仍然是本地的吗?

我不明白你在这里有多困惑;规则与Java完全相同。变量仍在范围内,因此它仍然存在。

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代码,尽管它可能不是你想要的。