在 Lua 中声明变量
了解全局变量与局部变量的区别,以及命名约定
在 Lua 中声明变量 是 CoddyKit 上的免费 Lua Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Lua Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Lua Academy 课程共包含 4 节课。
全局变量与局部变量
在 Lua 中,变量默认是全局变量。不使用 local 关键字而写下 x = 10,会创建一个可以从任何地方访问的全局变量。使用 local x = 10 则会将变量限制在当前代码块及其嵌套代码块中。
为了性能和安全性,请始终优先使用 local。访问局部变量比访问全局变量更快,因为全局变量需要在 _G 表中进行哈希查找。
x = 100 -- global variable
local y = 200 -- local variable
do
local z = 300 -- block-local
print(x, y, z) -- 100 200 300
end
print(x, y) -- 100 200
print(z) -- nil (out of scope)local 关键字
local 关键字会声明一个作用域限定在最近外层代码块中的变量。代码块可以是函数体、do...end 代码块、循环体或文件代码块。局部变量会在声明它的那一行创建,并在其代码块结束时不再存在。
您可以在一行中声明多个局部变量,并同时为它们赋初值。未初始化的局部变量默认值为 nil。
local a, b, c = 1, 2, 3
print(a, b, c) -- 1 2 3
local d, e = 10 -- e is nil
print(d, e) -- 10 nil
local f -- nil until assigned
f = 42
print(f) -- 42变量命名约定
Lua 标识符遵循以下规则:必须以字母或下划线开头,后面可以跟字母、数字或下划线。Lua 区分大小写,因此 Value、value 和 VALUE 是三个不同的变量。
按照 convention:普通变量使用 camelCase 或 snake_case,常量使用 UPPER_CASE,私有模块字段以下划线作为前缀。除循环计数器外,请避免使用单字母名称。
local myVariable = 1 -- camelCase
local my_variable = 2 -- snake_case
local MAX_SIZE = 100 -- constant convention
local _private = "hidden" -- private convention
-- Case sensitivity demo
local lua = "lower"
local Lua = "upper"
print(lua, Lua) -- lower upper_G 全局表
Lua 中的所有全局变量都存放在一个名为 _G 的特殊表中。写下 x = 10 等价于 _G.x = 10。您可以通过遍历 _G 查看所有全局变量,这对调试很方便,但用于生产代码时存在风险。
在 Lua 5.2+ 中,_ENV 是实际的环境表,而 _G 初始化时会指向它。理解这一点后,您就可以通过替换 _ENV 来为代码创建沙箱。
myGlobal = 42
print(_G.myGlobal) -- 42
-- Setting via _G is the same as direct assignment
_G.another = "hello"
print(another) -- hello
-- Counting globals (many built-ins exist)
local count = 0
for k in pairs(_G) do count = count + 1 end
print("Globals:", count)多重赋值
Lua 支持多重赋值:您可以在一条语句中为多个变量赋值。右侧表达式会先求值,然后从左到右进行赋值。如果变量多于值,多出的变量会得到 nil;如果值多于变量,多出的值会被丢弃。
因此,无需临时变量即可轻松交换变量。
-- Swap without temp variable
local a, b = 10, 20
a, b = b, a
print(a, b) -- 20 10
-- More variables than values
local x, y, z = 1, 2
print(x, y, z) -- 1 2 nil
-- More values than variables
local p, q = 1, 2, 3 -- 3 is discarded
print(p, q) -- 1 2作用域与代码块边界
Lua 的代码块分隔形式包括:do...end、函数体、if/elseif/else...end、while...end、repeat...until 和 for...end。每种形式都会创建一个新的作用域层级。do...end 代码块可以只用于限制作用域,而不包含其他逻辑。
在 for 循环头中声明的局部变量,其作用域限于循环体,不会泄漏到外部。
for i = 1, 3 do
local msg = "item " .. i
print(msg)
end
-- print(i) -- would be nil, i is gone
-- print(msg) -- would be nil, msg is gone
-- do...end for manual scoping
do
local temp = expensive_computation or 0
print(temp)
end
-- temp is nil here常量:local convention
Lua 没有内置的 const 关键字。通常使用 UPPER_CASE 名称和 local 来表示某个值不应发生变化。将常量作为局部变量放在模块顶部,还可以向即时编译器提示这些值是稳定的。
如果需要真正的不可变性,可以使用带有 __newindex 的代理表,在修改时触发错误——我们将在元表课程中介绍这一点。
local MAX_RETRIES = 3
local PI = 3.14159265358979
local APP_VERSION = "1.0.0"
-- Use them as read-only by convention
local area = PI * 5 * 5
print(area) -- 78.539...
print(MAX_RETRIES) -- 3变量遮蔽
当内层作用域声明了一个与外层变量同名的局部变量时,就会发生遮蔽。内层声明会创建一个全新的变量,在其作用域内隐藏外层变量。外层变量不会改变,并会在内层作用域结束后重新可见。
变量遮蔽可能令人困惑;请尽量在嵌套作用域中使用不同的名称,但有时遮蔽是有意为之的,例如在嵌套循环中重复使用循环变量名称。
local x = "outer"
do
local x = "inner" -- shadows outer x
print(x) -- inner
end
print(x) -- outer (unchanged)
local n = 10
for n = 1, 3 do -- loop n shadows outer n
print(n) -- 1, 2, 3
end
print(n) -- 10 (outer unchanged)避免污染全局环境
意外创建全局变量是 Lua 中常见的错误:误写局部变量名称会悄悄创建一个新的全局变量。strict.lua 模块(项目中通常会引入)通过向 _G 添加元表,捕获对未声明全局变量的读取和写入。
更简单的方法是始终使用 local,并运行 luac -p 或使用 luacheck 等代码检查工具,在运行前检测意外的全局变量。
-- Dangerous: typo creates a global silently
local counter = 0
coutner = 5 -- typo! creates global 'coutner'
print(counter) -- 0 (not 5!)
print(coutner) -- 5 (the typo global)
-- Fix: always use local keyword
local score = 0
score = 10 -- assigns to existing local
print(score) -- 10将 nil 赋值会删除全局变量
将全局变量设置为 nil 会从 _G 中移除它,并释放内存。这是“删除”全局变量的正确方式。对于局部变量,只需让它们超出作用域即可达到相同效果——垃圾回收器会回收相应内存。
在多重赋值中传入 nil 时请务必小心:在某些上下文中,尤其是右侧包含函数调用时,它可能会截断参数列表。
myGlobal = "exists"
print(myGlobal) -- exists
print(_G.myGlobal ~= nil) -- true
myGlobal = nil
print(myGlobal) -- nil
print(_G.myGlobal ~= nil) -- false
-- The entry is removed from _G快速检查
在 for 循环体内使用 local x = 5 声明的变量,其作用域是什么?
回顾:在 Lua 中声明变量
本课的要点:
- 变量默认是全局变量——请始终使用
local - 局部变量更快(无需哈希查找),也更安全
- 多重赋值:
a, b = b, a可在一行中完成交换 - 所有全局变量都存放在
_G中;将其设置为nil会删除它们 - 遮蔽:内层的
local会隐藏外层变量,但不会改变它 - 按照 convention,使用
UPPER_CASE表示常量
下一步:算术、关系和逻辑运算符。
常见问题解答
「在 Lua 中声明变量」课时是免费的吗?
是的 — 「在 Lua 中声明变量」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Lua Academy 课程的其余内容,请升级到 CoddyKit PRO。 Lua Academy 课程共包含 4 节课。
「在 Lua 中声明变量」这节课中我会学到什么?
了解全局变量与局部变量的区别,以及命名约定 你通过在浏览器中直接运行的动手代码来练习 Lua Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Lua Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Lua Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。
「在 Lua 中声明变量」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Lua Academy 课中编写并运行代码吗?
能。每节 Lua Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- Lua 数据类型概览
- 在 Lua 中声明变量
- 算术运算符和关系运算符
- 类型强制转换和显式转换