作为一个 Lua/Solar2D 新手(或相对较新的)程序员,您是否对类似这样的控制台错误感到困惑?
Runtime error /Users/yourname/Projects/AwesomeGame\menu.lua:4: attempt to index global 'button' (a nil value) stack traceback: [C]: in function 'error' ?: in function 'gotoScene' /Users/yourname/Projects/AwesomeGame\main.lua:16: in main chunk
如果是这样,那么您需要学习一个非常重要的编程概念,称为作用域。作用域会影响 Lua“看到”变量的能力
当您想到“望远镜”或“显微镜”之类的术语时,您会想到可以帮助您观察事物的设备,并且在一定范围内观察事物——例如,显微镜中的微小物体。在编程术语中,作用域用于定义代码的哪些部分可以“看到”您创建的变量、对象和函数。在 Lua 中,有两个主要的作用域控制:全局和局部。
全局变量/函数可以在程序中的任何位置被看到。“太好了,我将对所有内容使用全局作用域!”您可能会这么说,但全局对象实际上可能非常糟糕!事实上,新手程序员应该避免使用全局变量。
全局变量危险的原因之一是——由于它们没有可见性限制——它们在性能方面使用成本可能很高。事实上,如果在
全局变量/函数还具有被意外
告别全局变量!教程更详细地讨论了全局作用域,以及创建/访问
在 Lua 中,首选作用域是局部作用域,您可以通过在定义变量/函数之前使用 `local` 声明来控制它。例如
local someVariable
local function someFunction() end
当您在第一次创建变量或函数时在其前面加上 `local` 前缀时,它将对该代码块和其中包含的任何“子”代码块可用。以下两个示例突出了此概念
local function addTwoNumbers( number1, number2 ) -- Create variable "sum" local only to this "addTwoNumbers()" function local sum = number1 + number2 print( sum ) -- This works! end print( sum ) -- This does NOT work (prints "nil" meaning it's unknown to Lua)
在这种情况下,函数 `addTwoNumbers()` 定义了一个新的代码块。在此块内部,我们创建了一个名为 `sum` 的新变量。此变量带有 `local` 关键字,这意味着它仅对函数 `addTwoNumbers()` 可见——此模块或整个项目中的任何其他代码都无法“看到”`sum` 变量。因此,当函数结束时,不再存在名为 `sum` 的变量,并且 `nil` 将被打印到控制台。
local function addTwoNumbers( number1, number2 ) local sum = number1 + number2 if sum < 10 then print( sum .. " is less than 10" ) local secondSum = sum + 10 end print( secondSum ) -- This does NOT work (prints "nil" meaning it's unknown to Lua) end
与第一个示例一样,`sum` 是 `addTwoNumbers()` 的局部变量。这让我们可以将两个数字相加,并且它在由if sum < 10 then
if-then
if-then
if-then
考虑这样的代码块
local i = 999 for i = 1, 10 do print( i ) -- prints 1, 2, 3, .. 10 end print( i ) -- prints 999
这里,在第 1 行将局部变量 `i` 设置为 `999`。此外,使用了循环索引变量 `i`(第 3 行),但此 `i`仅对 `for` 循环是局部的。当循环执行时,它的值表示1
-10
print( i )
希望本教程已经说明,作用域作为一个整体概念相对简单。当您使用关键字 `local` 时,只能在该块级别或任何子块内访问该变量。考虑到这一点,如果您的变量或函数需要在更广泛的级别上可见,只需将它们移动到块上方/外部或在模块顶部附近定义它们。