控制結構

*此內容是使用 AI(Beta 測試版)翻譯,可能含有錯誤。若要以英文檢視此頁面,請按一下這裡

控制結構 是管理 Luau 代碼執行流程的聲明。有四種主要類型的控制結構:

  • 一個 如果然後 else 聲明只會執行代碼,如果指定的條件是 true 。代碼執行不會重複。
  • 一個 while 循環 只會執行代碼,如果指定的條件是 true,並且條件仍然是 true 時會重複執行。
  • A 重複循環 執行代碼,並在條件為 true 時重複執行。
  • 一個 循環 會依據指定的輸入執行代碼一定數量的次數。

if 句、while 循環和 repeat 循環的條件可以是任何 Luau 式或值。如果值不是 falsenil ,則 Luau 在條件聲明中評價它為 true 。與其他腳本語言不同,Luau 將零和空白字串視為 true

如果聲明

基本 if 聲明測試其條件。如果條件是真實的,則 Luau 會在 thenend 之間執行代碼。

您可以使用 elseif 聲明來測試額外條件,如果 if 條件為假。您可以使用 else 聲明來執行代碼,如果所有 ifelseif 條件都失敗。elseifelse 零件都是可選的,但你不能僅使用任何一個而無初始 if 聲明。

在一個 ifelseif 、和 else 條件的連鎖中,Luau測試條件從上到下,停留在第一個true 條件,然後執行隨後的代碼。


if 2 + 2 == 5 then
print("Two plus two is five") -- 因為條件是否定,所以不列印
elseif 2 + 3 == 5 then
print("Two plus three is five") -- 二加三是五
else
print("All conditions failed") -- 因為前一個條件是真實的,所以不列印
end

在循環中

一個 whiledo 循環評價是否滿足指定的條件是真是假。如果條件是 falsenil ,則循環結束,Luau 將在循環中跳過代碼。如果條件是 true ,則 Luau 在循環中執行代碼並重複過程。


local timeRemaining = 10
while timeRemaining > 0 do
print("Seconds remaining: " .. timeRemaining)
task.wait(1)
timeRemaining -= 1
end
print("Timer reached zero!")
--[[ 結果輸出:
Seconds remaining: 10
Seconds remaining: 9
Seconds remaining: 8
Seconds remaining: 7
Seconds remaining: 6
Seconds remaining: 5
Seconds remaining: 4
Seconds remaining: 3
Seconds remaining: 2
Seconds remaining: 1
Timer reached zero!
]]

無限循環

您可以使用 whiledo 循環來寫無限遊戲循環,通過設置 true 為條件來實現。


while true do
print("Looping...")
task.wait(0.5)
end
--[[ 結果輸出:
Looping...
Looping...
Looping...
Looping...
...
]]

重複循環

循環 repeatuntil 直到一個條件成真為止。條件測試在代碼塊運行後評估 ,因此代碼塊總是至少運行一次。與其他語言不同,在 repeatuntil 循環內宣言的本地變量範圍包括條件。


local currentGoblinCount = 18
-- 在遊戲中生成戈布林最多 25 個
repeat
spawnGoblin()
currentGoblinCount += 1
print("Current goblin count: " .. currentGoblinCount)
until currentGoblinCount == 25
print("Goblins repopulated!")
--[[ 結果輸出:
Current goblin count: 19
Current goblin count: 20
Current goblin count: 21
Current goblin count: 22
Current goblin count: 23
Current goblin count: 24
Current goblin count: 25
Goblins repopulated!
]]

對於循環

A 循環執行代碼的次數設為一個設定數量,可以是基於 數字計數器 或收集中的 項目數量

循環的數字

一個 fordo 循環決定使用計數器執行循環的次數。迴圈使用起始值、結束值和可選增量宣言。

Luau 將計數器設為與起始值相等,在 for 循環中執行代碼方塊,然後將增量添加到計數器。如果增量是正的,則過程會重複直到計數器與終值相等或大於終值為止。如果增量為負值,則過程會重複直到計數器與終值相等或小於終值為止。

可選增量默認為 1 。它不需要是整數。


for counter = 1, 3 do
print(counter)
end
--[[ 結果輸出:
1
2
3
]]
for counter = 1, 6, 2 do
print(counter)
end
--[[ 結果輸出:
1
3
5
]]
for counter = 2, 0, -0.5 do
print(counter)
end
--[[ 結果輸出:
2
1.5
1
0.5
0
]]

循環一般化

一般的 for 循環在收集中循環過項目而不是一個數字序列。使用一般 for 循環,您可以為收收藏中的每個項目執行代碼,並且可以簡單地使用代碼中的每個項目。

為了循環需要一個函數或迭代器來在不同類型的收集中循環。全球 ipairs() 返回陣列的迭代器,全球 pairs() 返回字典的迭代器。string 圖形庫提供 string.gmatch() 來循環過字串。

一般化的循環

在 Luau 中,您可以直接在表上使用 in 關鍵字來循環一個表,而不是使用迭代器函數,例如 ipairs() :


for i, v in {1, 2, 3, 4, 5} do
print(i, v)
end

一般化的循環也讓您使用 __iter 次級方法來創建自定義迭代器函數。這個示例嘗試在逆向順序中循環過一個陣列,從最後一個元素到第一個:


local myTable = {1, 2, 3, 4, 5}
myMetatable = {
__iter = function(t)
local i = #t + 1
return function()
i -= 1
if i > 0 then
return i, t[i]
end
end
end,
}
setmetatable(myTable, myMetatable)
for i, v in myTable do
print(i, v)
end
--[[ 結果輸出:
5 5
4 4
3 3
2 2
1 1
]]

陣列

ipairs() 功能返回一個迭代器,在表中循環通過數字索引並返回 indexvalue 對每個元素。這使得適合於所有指數都是數字的陣列。


local array = {"a", "b", "c", "d", "e"}
for index, value in ipairs(array) do
print(index, value)
end
--[[ 結果輸出:
1 a
2 b
3 c
4 d
5 e
]]

辭典

pairs() 函數返回一個迭代器,該迭代器會遍過表中所有索引(包括數字索引)並返回一個 keyvalue 對每個字典項目。字典表中元素的穿越順序是隨意的。這使得適合在辭典上循環,其中項目存儲在非數字指標之外的順序。


local dictionary = {
[1] = "a",
["Hello"] = "b",
[5] = "c",
[true] = "d",
["World"] = "f",
[false] = "e"
}
for key, value in pairs(dictionary) do
print(key, value)
end
--[[ 結果輸出:
Hello b
true d
false e
World f
5 c
1 a
]]

打破循環

若要強制循環結束,請使用 break 關鍵字。以下代碼示例顯示如何破壞無限 whiledo 循環。


local secondsElapsed = 0
local timeout = 5
while true do
task.wait(1)
secondsElapsed += 1
print("Seconds elapsed:", secondsElapsed)
if secondsElapsed == timeout then
break
end
end
print("Five seconds elapsed. Time to move on!")
--[[ 結果輸出:
1
2
3
4
5
Five seconds elapsed. Time to move on!
]]

繼續循環

若要強制循環重複並重新開始,請使用 continue 關鍵字。一個 for 循環將循環計數器;whilerepeatuntil 將在繼續前檢查循環條件。下面的代碼示例獲得特定 的所有子女。


local function GetChildrenOfClass(parent: Instance, className: string): {Instance}
local children = {}
for _, child in parent:GetChildren() do
if child.ClassName ~= className then continue end -- 循環遍歷
table.insert(children, child)
end
return children
end