Menu
Coddy logo textTech

定数テーブルのフリーズ

CoddyのLuaジャーニー「Luau入門」セクションの一部。レッスン 55/73。

定数テーブルには1つの弱点があります。それでも通常のtableなのです。どこにあるどんなコードでも UserRole.Admin = 99 と書き込めてしまい、「定数」はひっそりと定数ではなくなります。

Luauは table.freeze でこの隔たりを埋めます。凍結すると、tableは実行時に読み取り専用になります。フィールドの追加、変更、削除を試みると、errorが発生します。定番の書き方は、tableを構築したその場で凍結することです。table.freeze は同じtableを返すため、そのまま代入できます。

local Color = table.freeze({
    Red = 1,
    Green = 2,
    Blue = 3,
})

print(Color.Red) -- 1: 読み取りは通常どおり動作します
Color.Gold = 4   -- ✗ エラー: 読み取り専用テーブルを変更しようとしました

これまでこのコースで扱ってきた他のものとは異なり、これは実行時の保護です。編集時の警告ではなく、書き込みが実行された瞬間に発生する実際のerrorです。型チェッカーが一度も確認していないコードに対しても保護が働きます。

知っておく価値のある2つの関連機能があります。table.isfrozen(t) はtableが凍結されているかどうかを返します。また、凍結は浅い処理です。ネストされたtableは、それらも凍結しない限り変更可能なままです。さらに、凍結を解除することはできません。一度凍結されたtableは、凍結されたままです。

凍結された定数tableと、パラメーター用のリテラルユニオンを組み合わせれば、Luauのenumが完成します。誰にも改変できない名前付きの実行時値と、それらが使われるあらゆる場所での編集時チェックを実現できます。

challenge icon

チャレンジ

簡単

frozen な定数 Color という名前の table を作成し、table.freeze を使って構築と freeze を 1 つのステップで行い、次の内容を含めます。

  • Red = 1
  • Green = 2
  • Blue = 3

volume フィールドが 5 の、通常の(frozen ではない)settings という名前の table を作成します。

次の内容を、それぞれ別の行に出力します。

  1. Color.Red
  2. Color.Blue
  3. Color が frozen かどうか(table.isfrozen
  4. settings が frozen かどうか
  5. pcall 内で Color にフィールドを追加しようとした結果:pcall(function() Color.Gold = 4 end) を呼び出し、返される boolean を出力します

自分で試してみよう

-- ここにコードを書く
-- 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 する
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

Luau入門のすべてのレッスン

自分で練習してみよう: Luaオンラインコンパイラ