定数テーブルのフリーズ
CoddyのLuaジャーニー「Luau入門」セクションの一部 — レッスン 55/73。
定数 table には1つの弱点があります。それは、それが依然として普通の table であるということです。どこにあるどんなコードからでも UserRole.Admin = 99 と書き込むことができてしまい、定数であるはずのデータが静かに定数ではなくなってしまいます。
Luau は table.freeze でこの問題を解決します。table をフリーズすると、実行時に読み取り専用(read-only)になります。フィールドの追加、変更、削除の試みはすべて error を発生させます。慣習としては、構築したその場所で table をフリーズします。table.freeze は同じ table を返すため、そのまま代入できます:
local Color = table.freeze({
Red = 1,
Green = 2,
Blue = 3,
})
print(Color.Red) -- 1: 読み取りは通常どおり動作します
Color.Gold = 4 -- ✗ エラー: 読み取り専用テーブルを変更しようとしましたこのコースでこれまで扱ってきた他のものとは異なり、これは実行時(runtime)の保護です。write が実行された瞬間に実際の error が発生するものであり、編集時の警告ではありません。型チェッカーが認識していないコードからでも保護します。
知っておくべき2つの補足事項:table.isfrozen(t) は table が frozen かどうかを返し、フリーズは浅い(shallow)処理です — ネストされた table もフリーズしない限り mutable(変更可能)のままです。また、フリーズを解除することはできません。一度フリーズされた table は frozen のままです。
フリーズされた定数 table とパラメータ用のリテラルユニオンの組み合わせこそが、完全な Luau の enum です。誰も改ざんできない名前付きの実行時値と、それが使用されるあらゆる場所での編集時チェックを提供します。
チャレンジ
簡単Color という名前のフリーズされた定数 table を作成します — table.freeze を使用して1つの step で build し、freeze します。内容は以下の通りです:
Red=1Green=2Blue=3
フィールド volume = 5 を持つ、通常の(frozen されていない)table である settings を作成します。
それぞれ新しい行に以下を出力します:
Color.RedColor.BlueColorがfrozen状態かどうか(table.isfrozen)settingsがfrozen状態かどうかpcallの中でColorにフィールドを追加しようとした結果 —pcall(function() Color.Gold = 4 end)を呼び出し、それが返すbooleanをprintします
自分で試してみよう
-- ここにコードを書いてください
-- 1) local Color = table.freeze({Red = 1, Green = 2, Blue = 3})
-- 2) local settings = {volume = 5}
-- 3) print Color.Red, Color.Blue, 両方の isfrozen の結果
-- 4) 禁止された書き込みを pcall し、返された boolean を print する
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
Luau入門のすべてのレッスン
7プロジェクト:Typed Task Manager
プロジェクト:タスクの型定義タスクを追加する関数8Enum、Luau流のアプローチ
LuauにおけるEnumパターンテーブルによる数値Enumユニオン型としての文字列EnumリテラルユニオンEnumの活用定数テーブルのフリーズまとめ:Enum、Luau流のアプローチ