厳格モードにおける Nil 安全性
CoddyのLuaジャーニー「Luau入門」セクションの一部 — レッスン 71/73。
Luaで最も一般的なクラッシュは "attempt to index nil" です。これは、値が存在することを前提としたコードでその値が存在しなかった場合に発生します。Luauの解決策は nil discipline です。--!strict の下では、通常の string が nil になることは 絶対にあり得ません。nil の可能性がある場合は、? を使って型で明示する必要があります:
--!strict
local nickname: string? = nil -- ok: string または nil
local username: string = nil -- ✗ 厳格モードでの型エラーこのルールは双方向に作用します。string? が与えられた場合、strict モードでは nil を除外(rule out) するまで、それを文字列として扱うことはできません。標準的な手段は通常の比較であり、typeof ガードと同じように型を絞り込みます:
local function shout(name: string?): string
if name ~= nil then
return string.upper(name) -- ここで name は string です
end
return "NOBODY"
endnil が正常なケースではなくバグとなる場合は assert を使用します。assert(x ~= nil) の後、型チェッカーはスコープの残りの部分で x を非nilとして扱います。また、実行時には、前提が崩れた時点で早期にクラッシュするため、遠く離れた場所でエラーが発生するのを防ぎます。
その利点として、編集時に「欠落している可能性がある」すべての値を型チェッカーが処理するように強制するため、実行時エラーは決して発生しなくなります。
チャレンジ
簡単欠けている可能性のあるユーザープロファイルフィールドを処理します。ファイルの先頭に --!strict を指定してください。
getDisplayName(fullName: string?): string—fullNameがnilでない場合はfullNameを返し、それ以外の場合はAnonymous Userを返します。formatEmail(email: string?): string—emailがnilでない場合は小文字に変換したメールアドレス(string.lower)を返し、それ以外の場合はNo email providedを返します。getUserInfo(name: string?, email: string?): string— 両方の関数を使用してName: [processed name], Email: [processed email]を返します。
その後、それぞれを改行して出力します:
getDisplayName("John Smith")getDisplayName(nil)formatEmail("ALICE@EXAMPLE.COM")formatEmail(nil)getUserInfo("Bob Johnson", "bob@test.com")getUserInfo(nil, nil)getUserInfo("Sarah Wilson", nil)
自分で試してみよう
--!strict
-- ここにコードを書く
-- 1) getDisplayName(fullName: string?): string — nil-check, fallback "Anonymous User"
-- 2) formatEmail(email: string?): string — string.lower or "No email provided"
-- 3) getUserInfo(name: string?, email: string?): string — 両方を組み合わせる
-- 4) タスクの7つのテスト呼び出しを出力する
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
Luau入門のすべてのレッスン
7プロジェクト:Typed Task Manager
プロジェクト:タスクの型定義タスクを追加する関数