控制結構是管理 Luau 代碼執行流程的語句。主要有四種類型的控制結構:
- if then else 語句僅在指定條件為 true 時執行代碼。代碼的執行不會重複。
- repeat loop 會執行代碼,如果條件為 true 則重複執行。
- for loop 會根據指定輸入執行代碼一定的次數。
if 語句、while 循環和 repeat 循環的條件可以是任何 Luau 表達式或值。如果一個值不是 false 或 nil,則 Luau 在條件語句中會將其評估為 true。與其他腳本語言不同,Luau 將零和空字符串都視為 true。
If 語句
基本的 if 語句測試其條件。如果條件為真,則 Luau 執行 then 和 end 之間的代碼。
如果 if 條件為假,可以使用 elseif 語句來測試其他條件。如果所有的 if 和 elseif 條件都未通過,可以使用 else 語句執行代碼。elseif 和 else 部分都是可選的,但不能在沒有初始 if 語句的情況下使用它們。
在一系列的 if、elseif 和 else 條件中,Luau 從上到下檢查條件,在遇到第一個 true 條件時停止執行,並執行其後的代碼。
if 2 + 2 == 5 then
print("兩加二為五") -- 不會打印,因為條件是假的
elseif 2 + 3 == 5 then
print("兩加三為五") -- 兩加三為五
else
print("所有條件都失敗") -- 不會打印,因為前一條件為真
endWhile 循環
while—do 循環評估指定的條件是否為真或假。如果條件為 false 或 nil,則循環結束,Luau 跳過循環中的代碼。如果條件為 true,則 Luau 執行循環中的代碼並重複該過程。
local timeRemaining = 10
while timeRemaining > 0 do
print("剩餘秒數: " .. timeRemaining)
task.wait(1)
timeRemaining -= 1
end
print("計時器到達零了!")
--[[ 結果輸出:
剩餘秒數: 10
剩餘秒數: 9
剩餘秒數: 8
剩餘秒數: 7
剩餘秒數: 6
剩餘秒數: 5
剩餘秒數: 4
剩餘秒數: 3
剩餘秒數: 2
剩餘秒數: 1
計時器到達零了!
]]無限循環
可以使用 while—do 循環來編寫無限遊戲循環,條件設置為 true。
while true do
print("循環中...")
task.wait(0.5)
end
--[[ 結果輸出:
循環中…
循環中…
循環中…
循環中…
...
]]Repeat 循環
repeat—until 循環在條件為真之前不斷重複執行。條件測試在代碼塊運行後進行,因此代碼塊始終至少運行一次。與其他語言不同,Luau 中在 repeat—until 循環內部聲明的局部變量的範圍包括條件。
local currentGoblinCount = 18
-- 在遊戲中生成最多 25 隻哥布林
repeat
spawnGoblin()
currentGoblinCount += 1
print("當前哥布林數量: " .. currentGoblinCount)
until currentGoblinCount == 25
print("哥布林已重新繁殖!")
--[[ 結果輸出:
當前哥布林數量: 19
當前哥布林數量: 20
當前哥布林數量: 21
當前哥布林數量: 22
當前哥布林數量: 23
當前哥布林數量: 24
當前哥布林數量: 25
哥布林已重新繁殖!
]]For 循環
for 循環執行一定次數的代碼,可以根據 數字計數器 或 集合中的項目數量 來進行。
數字 for 循環
for—do 循環通過計數器來確定執行循環的次數。循環由起始值、結束值和可選增量聲明。
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 循環迭代集合中的項目,而不是數字序列。使用通用 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() 函數返回一個通過數字索引遍歷表的迭代器,並返回每個元素的 index 和 value。這使它適合於數組,其中所有索引都是數字。
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() 函數返回一個通過表中所有索引(包括數字索引)進行遍歷的迭代器,並為字典中的每個條目返回 key 和 value。遍歷字典表中元素的順序是任意的。這使它適合於遍歷字典,其中項目以非數字索引以無序的方式存儲。
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 關鍵字。以下代碼示例顯示如何打破無限的 while—do 循環。
local secondsElapsed = 0
local timeout = 5
while true do
task.wait(1)
secondsElapsed += 1
print("已經過秒數:", secondsElapsed)
if secondsElapsed == timeout then
break
end
end
print("五秒過去了。該繼續了!")
--[[ 結果輸出:
1
2
3
4
5
五秒過去了。該繼續了!
]]繼續循環
要強制循環進行並重新開始,使用 continue 關鍵字。for 循環將迭代計數器;while 和 repeat—until 將在繼續之前檢查循環條件。以下代碼示例獲取特定 ClassName 的 Instance 的所有子項。
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