リテラルユニオンEnumの活用
CoddyのLuaジャーニー「Luau入門」セクションの一部 — レッスン 54/73。
リテラルユニオンは関数のパラメータとしてその真価を発揮します。パラメータにユニオン型を指定すると、チェッカーはその関数が有効なメンバーでのみ呼び出されることを保証します:
type Direction = "up" | "down" | "left" | "right"
local function move(direction: Direction)
print(`Moving {direction}...`)
end
move("left") -- ✓
move("north") -- ✗ 型エラー: Direction ではない関数内では、if/elseif チェーンを使ってメンバーを網羅的(exhaustive)に処理します。型によって入力が four つの値に制限されているため、3つの値をチェックし、最後の1つを else に処理させればすべてをカバーできます:
local function describe(direction: Direction): string
if direction == "up" then
return "Going upward"
elseif direction == "down" then
return "Going downward"
elseif direction == "left" then
return "Turning left"
else
return "Turning right"
end
end1つ注意点があります。io.read() などの外部から受け取る文字列は、ユーザーが何を入力するかチェッカーには分からないため、plain な string として型付けされます。以前学んだ :: による型キャスト(cast)を使えば、その値を列挙型として扱うようチェッカーに指示できます:
local direction = io.read() :: Directionキャストはアサーション(約束)であり、検証ではありません。実行時に入力値がチェックされるわけではない点に注意してください。プロダクションコードでは事前にバリデーションを行いますが、ここでは型定義された関数がユーザー入力をスマートに受け取れるようにするために使用しています。
チャレンジ
簡単メンバー "up"、"down"、"left"、"right" を持つリテラルユニオン型 Direction を作成してください。
direction: Direction を受け取り、Moving [direction]... と出力する関数 move を作成してください。
direction: Direction を受け取り、string を返し、if/elseif/else で全てのメンバーを処理する関数 getMovementDescription を作成してください:
"up"→Going upward"down"→Going downward"left"→Turning left"right"→Turning right
io.read() でユーザーから1行読み込み、:: を使って Direction にキャストしてください。その後:
- その
directionでmoveを呼び出します - 同じ
directionに対してgetMovementDescriptionの結果を出力します
自分で試してみよう
-- ここにコードを書いてください
-- 1) 型 Direction を定義する
-- 2) move と getMovementDescription を書く (if/elseif/else)
-- 3) 入力を読み取る: local direction = io.read() :: Direction
-- 4) move を呼び出し、その後 description を出力する
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
Luau入門のすべてのレッスン
7プロジェクト:Typed Task Manager
プロジェクト:タスクの型定義タスクを追加する関数8Enum、Luau流のアプローチ
LuauにおけるEnumパターンテーブルによる数値Enumユニオン型としての文字列EnumリテラルユニオンEnumの活用定数テーブルのフリーズまとめ:Enum、Luau流のアプローチ