Lua 变量的作用域

我知道还有其他类似的主题,但找不到我的问题的直接答案。 假设您有一个函数,例如:

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

在 if 语句内部的 aLuaTable 变量仍然是局部的吧?基本上,我要问的是,如果我第一次将变量定义为 local,然后我再次使用它并使用任意次数,它是否会保持为局部变量在程序其余的生命周期内,这如何工作?

此外,我读到了Lua全局变量的定义:

任何不在定义块中的变量都说在全局范围内。 在全局范围内的任何内容都可被内部范围访问。

什么是“未在定义块中”?我的理解是,如果我在任何地方“声明”一个变量,它将始终是全局的,这不正确吗?

如果问题太简单,请原谅,但从 Java 和 objective-c,Lua 对我来说非常奇怪。

原文链接 https://stackoverflow.com/questions/10654823

点赞
stackoverflow用户734069
stackoverflow用户734069

对于 if 语句中的 aLuaTable 变量,它还是局部变量,对吗?

我不明白你为什么会感到困惑;规则与 Java 完全相同。变量仍处于作用域内,因此它继续存在。

“local” 变量相当于在 Java 中定义“stack” 变量。变量存在于定义它的块作用域内,在该块结束时则停止存在。

考虑以下 Java 代码:

public static void main()
{
  if(...)
  {
    int aVar = 5; //aVar 存在。
    if(...)
    {
      aVar = 10; //aVar 继续存在。
    }
  }

  aVar = 20; //编译错误:aVar 在“}”处停止存在。
}

“全局变量”是任何非局部变量的变量名。考虑与上述 Java 代码相等的Lua 代码:

function MyFuncName()
  if(...) then
    local aVar = 5 --aVar 存在且是局部变量。

    if(...) then
      aVar = 10 --由于符号`aVar`在作用域内最近的声明是一个“local”,所以这里的使用是指上面定义的“local”。
    end
  end

  aVar = 20 --上一个“local aVar” *不在作用域内*。该作用域在上述`end`中结束。因此,这个“aVar”指的是*全局* aVar。
end

在 Java 中是编译错误的,在 Lua 中是完全有效的代码,但这可能不是你想要的结果。

2012-05-18 15:17:14
stackoverflow用户501459
stackoverflow用户501459

任何没有定义在一个特定代码块中的变量都被视为全局作用域。

这是错误的,所以你的困惑是可以理解的。看起来你从用户维基页面获取了这个信息。我刚刚更新了页面上的信息纠正:

任何没有使用 local 定义的变量都是全局变量。

我的理解是,如果在任何地方“声明”一个变量,它将永远是全局的

如果你没有将其定义为 local,它将是全局的。然而,如果你创建了一个同名的 local,它将优先于全局变量(即在尝试解析变量名时,Lua “看到”局部变量优先于全局变量)。请参见本文底部的示例。

如果我第一次将变量定义为 local,然后我再次使用它,并且使用任意数量的次数,它会一直保持局部吗?具体如何实现?

当你的代码被编译时,Lua 会跟踪你定义的所有局部变量,并知道哪些变量在给定的作用域中可用。每当你读/写变量时,如果在该范围内有可用的局部变量,则使用它。否则,在编译时将读/写转换为表读/写(通过表 _ENV)。

local x = 10 -- 存储在 VM 寄存器(C 数组)中
y = 20       -- 转换为 _ENV["y"] = 20

x = 20       -- 写入与 x 相关联的 VM 寄存器
y = 30       -- 转换为 _ENV["y"] = 30

print(x)     -- 从 VM 寄存器中读取
print(y)     -- 转换为 print(_ENV["y"])

局部变量是词法作用域的。其他所有东西都存放在 _ENV 中。

x = 999

do -- 创建一个新作用域
    local x = 2
    print(x)      -- 使用局部变量 x,因此我们打印 2
    x = 3         -- 写入相同的局部变量
    print(_ENV.x) -- 显式引用我们的局部变量所隐藏的全局变量 x 
end

print(x) -- 打印 999
2012-05-18 17:05:44