スクリプトでは、コードのブロックは制御構造または関数の本体です。変数または関数のスコープは、それにアクセスできるコードのブロックであり、グローバルまたはローカルである可能性があります。すべてのブロックはグローバル変数と関数にアクセスできます。ブロックは親ブロック内のローカル変数と関数にアクセスできますが、子ブロック内のものにはアクセスできません。
変数と関数はデフォルトでグローバルスコープを持ちますが、ローカルスコープで宣言する方がほとんどの場合は良いです。なぜなら、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 do
x += 1
print("グローバル 'x' = " .. x)
end
print("グローバル 'x' = " .. x)
--[[ 結果の出力:
グローバル 'x' = 1
グローバル 'x' = 2
グローバル 'x' = 3
グローバル 'x' = 4
グローバル 'x' = 4
]]グローバル変数と関数を宣言するのは簡単ですが、ローカルなものと比較して以下の欠点があります。
- Luauはグローバル変数と関数にハッシュルックアップでアクセスするため、パフォーマンスの観点からコストがかかります。時間が重要なループでグローバル変数を使用すると、同じループ内のローカル変数を使用するよりも10%以上遅くなることがあります。
- Luauはスコープが終了した後にローカル変数を破棄し、メモリ使用量を削減します。
ローカルスコープ
Luauは、宣言したコードのブロック内でのみローカル変数または関数にアクセスできます。ローカルスコープで変数を作成すると、その値が変更されるタイミングと場所をより厳密に制御できます。
次のコードでは、testFunc()関数とtestVar変数はローカルスコープを持ちます。testFunc()内のコードのみがtestVar変数にアクセスできます。testVar変数はtestFunc()の外部では値を持たないため、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は初期の変数xを変更されていない値0で出力します。
local x = 0 -- ローカル変数 "x"
for i = 1, 4 do
local x = 1 -- 異なる変数 "x"、この "for" ループにローカル
print("ループ 'x' = " .. x)
end
print("初期 'x' = " .. x)
--[[ 結果の出力:
ループ 'x' = 1
ループ 'x' = 1
ループ 'x' = 1
ループ 'x' = 1
初期 'x' = 0
]]const変数と関数はlocalと同じスコープルールに従います。これらは、他の関数の内部を含む任意のブロックで宣言できます。constに関する詳細は、Const変数を参照してください。
キャプチャ
ローカル変数を宣言して割り当てた後、そのスコープレベルおよびローカル変数を含む同じスコープに囲まれた関数内でそれを読み取ることができます。この技術はキャプチャとして知られています。
次のコードでは、関数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ループがあります。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