控制结构是管理 Luau 代码执行流程的语句。主要有四种类型的控制结构:
- 一个 if then else 语句仅在指定条件为 true 时执行代码。代码执行不会重复。
- 一个 repeat 循环 执行代码,并在条件为 true 时重复执行。
- 一个 for 循环 根据指定输入执行固定次数的代码。
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 循环直到条件为真才会重复。条件测试在代码块运行 之后 进行评估,因此代码块始终至少执行一次。与其他语言不同的是,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