冻结常量表
本课属于 Coddy Lua 学习旅程的“Luau 入门”单元。第 59 课,共 80 课。
常量表有一个弱点:它仍然是普通表。任何地方的任何代码都可以写入 UserRole.Admin = 99,这样你的“常量”就会悄悄不再是常量。
Luau 通过 table.freeze 弥补了这个缺口。冻结会让表在运行时只读:任何添加、更改或删除字段的尝试都会引发错误。惯用做法是在创建表时就将其冻结:table.freeze 会返回同一个表,可以直接赋值:
local Color = table.freeze({
Red = 1,
Green = 2,
Blue = 3,
})
print(Color.Red) -- 1:读取操作照常进行
Color.Gold = 4 -- ✗ 错误:尝试修改只读表与这门课程到目前为止介绍的其他内容不同,这是运行时保护:写入操作一执行就会产生真正的错误,而不是编辑时警告。它甚至能防止类型检查器从未检查过的代码造成修改。
还有两个值得了解的配套功能:table.isfrozen(t) 会返回表是否已冻结;冻结是浅层的:嵌套表仍然可以修改,除非你也把它们冻结。你也无法解冻:表一旦冻结,就会一直保持冻结状态。
冻结的常量表加上用于参数的字面量联合类型,就构成了完整的 Luau 枚举:命名的运行时值无人能够篡改,并且在使用这些值的任何地方都能进行编辑时检查。
挑战
简单创建一个无法更改的常量表。
- 创建
local Size = table.freeze({Small = 1, Medium = 2, Large = 3})。 - 打印
Size.Large和table.isfrozen(Size)。 - 将
pcall(function() Size.Huge = 4 end)存入local ok,然后打印ok。
按“运行代码”:输出会显示 3、true 和 false。
亲手试试
-- 1) local Size = table.freeze({...})
-- 2) print Size.Large and table.isfrozen(Size)
-- 3)将禁止写入时 pcall 的返回值存入 ok,然后打印它。
Luau 入门中的所有课
自己练习: Luau 在线编译器