Menu
Coddy logo textTech

リテラルユニオン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
end

1つ注意点があります。io.read() などの外部から受け取る文字列は、ユーザーが何を入力するかチェッカーには分からないため、plainstring として型付けされます。以前学んだ :: による型キャスト(cast)を使えば、その値を列挙型として扱うようチェッカーに指示できます:

local direction = io.read() :: Direction

キャストはアサーション(約束)であり、検証ではありません。実行時に入力値がチェックされるわけではない点に注意してください。プロダクションコードでは事前にバリデーションを行いますが、ここでは型定義された関数がユーザー入力をスマートに受け取れるようにするために使用しています。

challenge icon

チャレンジ

簡単

メンバー "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 にキャストしてください。その後:

  1. その directionmove を呼び出します
  2. 同じ direction に対して getMovementDescription の結果を出力します

自分で試してみよう

-- ここにコードを書いてください
-- 1) 型 Direction を定義する
-- 2) move と getMovementDescription を書く (if/elseif/else)
-- 3) 入力を読み取る: local direction = io.read() :: Direction
-- 4) move を呼び出し、その後 description を出力する
quiz icon腕試し

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

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