Menu
CoddyTech

Замораживание константных таблиц

Часть раздела Введение в Luau путешествия по Lua на Coddy. Урок 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.

Нажми Run Code: вывод показывает 3, true и false.

Попробуйте сами

-- 1) local Size = table.freeze({...})
-- 2) выведите Size.Large и table.isfrozen(Size)
-- 3) сохраните в ok значение, которое возвращает pcall при запрещённой записи, и выведите его

Все уроки раздела Введение в Luau

Потренируйтесь самостоятельно: Онлайн-компилятор Luau