スクリプトにおいて、コードのブロックは制御構造または関数の本体です。変数または関数のスコープは、それにアクセスできるコードのブロックであり、グローバルまたはローカルのいずれかです。すべてのブロックはグローバル変数と関数にアクセスできます。ブロックは親ブロック内のローカル変数と関数にアクセスできますが、子ブロック内の変数や関数にはアクセスできません。
変数や関数はデフォルトでグローバルスコープを持ちますが、Luauではローカルスコープで宣言する方がほとんどの場合は良いです。なぜなら、ローカル変数および関数はグローバルなものよりも高速にアクセスされるためです。変数または関数にローカルスコープを与えるには、宣言時にその名前の前にlocalキーワードを置きます。
スクリプトは他のスクリプトのグローバルおよびローカル変数や関数にアクセスできません。スクリプト間で値や関数を共有したい場合は、ModuleScriptsを使用してください。
local helloWorld = 'Hello World!'
local function printHelloWorld()
print(helloWorld)
end
printHelloWorld() -- Hello World!

- ブロックBはブロックAのローカル変数にアクセスできます。
- ブロックCはブロックAとBのローカル変数および関数にアクセスできます。
- ブロックAはブロックBまたはCのローカル変数と関数にアクセスできません。
- ブロックBはブロックCのローカル変数にアクセスできません。
グローバルスコープ
グローバル変数や関数を宣言した後、同じスクリプト内の任意のコードのブロックがそれにアクセスできます。変数や関数は、localキーワードで宣言しない限り、グローバルスコープを持ちます。
以下のコードでは、testVarはローカルtestFunc()関数内でグローバルスコープを持ちます。LuauがtestFunc()を呼び出すと、testVarに64が代入されます。testVarはグローバルスコープにあるため、testFunc()の外にあるprint()関数がそれにアクセスして64を出力できます。
グローバル関数と変数の例
local function testFunc() -- ローカルスコープ
testVar = 64 -- グローバルスコープ
end
testFunc()
print(testVar) -- 64
以下のコードでは、グローバル変数xは最初に0から始まり、forループの各イテレーションで1ずつ増加し、その後最終的な値4で再度出力されます。
x = 0 -- グローバル変数 "x"for i = 1, 4 dox += 1print("グローバル 'x' = " .. x)endprint("グローバル 'x' = " .. x)--[[ 結果の出力:グローバル 'x' = 1グローバル 'x' = 2グローバル 'x' = 3グローバル 'x' = 4グローバル 'x' = 4]]
グローバル変数や関数を宣言するのは簡単ですが、ローカルのものに比べて次のような欠点があります:
- Luauはグローバル変数および関数にハッシュルックアップを使用するため、パフォーマンスの面で高コストです。時間が重要なループでグローバル変数を使用すると、同じループ内のローカル変数を使用するよりも10%以上遅くなる可能性があります。
- Luauはローカル変数のスコープが終了すると、それを無効にし、メモリ使用量を減らします。
ローカルスコープ
Luauは、宣言したコードのブロック内でのみローカル変数または関数にアクセスできます。ローカルスコープの変数を作成すると、その値が変更されるタイミングと場所をより厳密にコントロールできます。
以下のコードでは、testFunc()関数とtestVar変数はローカルスコープを持ちます。testFunc()内のコードだけがtestVar変数にアクセスできます。testFunc()の外ではtestVar変数に値がないため、testFunc()内でprint(testVar)を呼び出すとtestVarの値が出力されますが、testFunc()の外でprint(testVar)を呼び出すとnilが出力されます。
local function testFunc() -- ローカルスコープ
local testVar = 64 -- ローカルスコープ
print(testVar) -- 64
end
testFunc()
print(testVar) -- nil
以下のコードでは、ローカル変数xは1行目で値0を持ちます。Luauがforループを反復処理する間、異なるローカル変数xが値1を持ちます。次に、Luauは変更されていない値0で初期変数xを出力します。
local x = 0 -- ローカル変数 "x"for i = 1, 4 dolocal x = 1 -- 異なる変数 "x", この "for" ループにローカルprint("ループ 'x' = " .. x)endprint("初期 'x' = " .. x)--[[ 結果の出力:ループ 'x' = 1ループ 'x' = 1ループ 'x' = 1ループ 'x' = 1初期 'x' = 0]]
キャプチャ
ローカル変数を宣言して代入すると、そのスコープレベルおよびローカル変数を含むスコープ内の関数でそれを読み取ることができます。この技術はキャプチャとして知られています。
以下のコードでは、関数fがローカル変数xをキャプチャします。f()内の変数xはアップバリューです。
local x = 5
local function f()
print(x)
end
f() -- 5
print(x) -- 5
シャドウ
ローカル変数を宣言して代入すると、そのスコープレベルおよび子孫スコープレベルでそれを読み取ることができます。子孫スコープレベルで変数を再宣言して再代入すると、最も最近の代入とは異なる値を持つ同じ名前の新しいローカル変数を作成します。新しいローカル変数は、以前の代入のローカル変数には影響を与えません。この技術はシャドウイングとして知られ、変数の名前を再利用することができますが、値は再利用しません。
以下のコードでは、Luauは変数xをシャドウします。関数f()内の変数xはシャドウ変数です。
local x = 5
local function f()
local x = 7
print(x)
end
f() -- 7
print(x) -- 5
また、値を割り当てずにローカル変数を再宣言することもでき、スコープレベルと子孫スコープレベルの両方で変数を再代入できます。値を割り当てずにローカル変数を再宣言すると、その値はnilに設定されます。
以下のコードでは、Luauは関数getFruitByColor()内でローカル変数fruitNameをシャドウします。この関数はfruitNameを新しいシャドウ変数として再宣言し、値をnilに設定します。関数には、fruitNameに値を割り当てるforループという子孫スコープレベルがあります。ループの後、関数はfruitNameシャドウ変数を返します。関数全体を通じて、fruitNameは初期のfruitNameローカル変数を上書きしない同じローカル変数です。
local fruitName = "Chocolate"
local fruitTable = {
Lemon = "Yellow",
Apple = "Red",
Orange = "Orange"
}
local function getFruitByColor(color)
local fruitName
for key, value in fruitTable do
if value == color then
fruitName = key
end
end
return fruitName
end
local fruit = getFruitByColor("Yellow")
print(fruit) -- Lemon
print(fruit .. ", not " .. fruitName) -- Lemon, not Chocolate