Menu
CoddyTech

冻结常量表

本课属于 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 枚举:命名的运行时值无人能够篡改,并且在使用这些值的任何地方都能进行编辑时检查。

challenge icon

挑战

简单

创建一个无法更改的常量表。

  1. 创建 local Size = table.freeze({Small = 1, Medium = 2, Large = 3})。
  2. 打印 Size.Large 和 table.isfrozen(Size)。
  3. 将 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 在线编译器