控制結構是管理 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 thenprint("兩加二為五") -- 不會打印,因為條件是假的elseif 2 + 3 == 5 thenprint("兩加三為五") -- 兩加三為五elseprint("所有條件都失敗") -- 不會打印,因為前一條件為真end
While 循環
while—do 循環評估指定的條件是否為真或假。如果條件為 false 或 nil,則循環結束,Luau 跳過循環中的代碼。如果條件為 true,則 Luau 執行循環中的代碼並重複該過程。
local timeRemaining = 10while timeRemaining > 0 doprint("剩餘秒數: " .. timeRemaining)task.wait(1)timeRemaining -= 1endprint("計時器到達零了!")--[[ 結果輸出:剩餘秒數: 10剩餘秒數: 9剩餘秒數: 8剩餘秒數: 7剩餘秒數: 6剩餘秒數: 5剩餘秒數: 4剩餘秒數: 3剩餘秒數: 2剩餘秒數: 1計時器到達零了!]]
無限循環
可以使用 while—do 循環來編寫無限遊戲循環,條件設置為 true。
while true doprint("循環中...")task.wait(0.5)end--[[ 結果輸出:循環中…循環中…循環中…循環中…...]]
Repeat 循環
repeat—until 循環在條件為真之前不斷重複執行。條件測試在代碼塊運行後進行,因此代碼塊始終至少運行一次。與其他語言不同,Luau 中在 repeat—until 循環內部聲明的局部變量的範圍包括條件。
local currentGoblinCount = 18-- 在遊戲中生成最多 25 隻哥布林repeatspawnGoblin()currentGoblinCount += 1print("當前哥布林數量: " .. currentGoblinCount)until currentGoblinCount == 25print("哥布林已重新繁殖!")--[[ 結果輸出:當前哥布林數量: 19當前哥布林數量: 20當前哥布林數量: 21當前哥布林數量: 22當前哥布林數量: 23當前哥布林數量: 24當前哥布林數量: 25哥布林已重新繁殖!]]
For 循環
for 循環執行一定次數的代碼,可以根據 數字計數器 或 集合中的項目數量 來進行。
數字 for 循環
for—do 循環通過計數器來確定執行循環的次數。循環由起始值、結束值和可選增量聲明。
Luau 將計數器設為起始值,執行 for 循環中的代碼塊,然後將增量加到計數器。如果增量為正,則該過程重複,直到計數器等於或大於結束值。如果增量為負,則該過程重複,直到計數器等於或小於結束值。
可選的增量默認為 1。它不必是一個整數。
for counter = 1, 3 doprint(counter)end--[[ 結果輸出:123]]for counter = 1, 6, 2 doprint(counter)end--[[ 結果輸出:135]]for counter = 2, 0, -0.5 doprint(counter)end--[[ 結果輸出:21.510.50]]
通用 for 循環
通用 for 循環迭代集合中的項目,而不是數字序列。使用通用 for 循環,可以針對集合中的每個項目執行代碼,並且可以輕鬆使用每個項目。
for 循環需要一個函數或迭代器來遍歷各種類型的集合。全局的 ipairs() 返回一個數組的迭代器,而全局的 pairs() 返回一個字典的迭代器。string 庫提供 string.gmatch() 用於迭代字符串。
泛化迭代
在 Luau 中,可以直接在表上使用 in 關鍵字來進行迭代,而不需要使用像 ipairs() 這樣的迭代器函數:
for i, v in {1, 2, 3, 4, 5} doprint(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) doprint(index, value)end--[[ 結果輸出:1 a2 b3 c4 d5 e]]
字典
pairs() 函數返回一個通過表中所有索引(包括數字索引)進行遍歷的迭代器,並為字典中的每個條目返回 key 和 value。遍歷字典表中元素的順序是任意的。這使它適合於遍歷字典,其中項目以非數字索引以無序的方式存儲。
local dictionary = {[1] = "a",["Hello"] = "b",[5] = "c",[true] = "d",["World"] = "f",[false] = "e"}for key, value in pairs(dictionary) doprint(key, value)end--[[ 結果輸出:Hello btrue dfalse eWorld f5 c1 a]]
中斷循環
要強制終止循環,使用 break 關鍵字。以下代碼示例顯示如何打破無限的 while—do 循環。
local secondsElapsed = 0local timeout = 5while true dotask.wait(1)secondsElapsed += 1print("已經過秒數:", secondsElapsed)if secondsElapsed == timeout thenbreakendendprint("五秒過去了。該繼續了!")--[[ 結果輸出:12345五秒過去了。該繼續了!]]
繼續循環
要強制循環進行並重新開始,使用 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