Lua repeat…until 循环(完整教程)

Lua repeat…until 循环详解:从入门到实战

在 Lua 编程语言中,循环结构是控制程序流程的核心工具之一。相比常见的 forwhile 循环,repeat…until 循环有着独特的优势——它保证循环体至少执行一次,非常适合需要“先执行后判断”的场景。如果你正在学习 Lua,或者想更深入理解循环机制,那么掌握 repeat…until 循环将为你打开一扇新的大门。

我们今天就来系统地拆解这个结构,从语法基础到实际应用,用真实代码说话,帮助你真正“用起来”。


基本语法结构与执行逻辑

repeat…until 循环的语法非常简洁,结构如下:

repeat
    -- 循环体内的代码
until 条件表达式

它的执行逻辑是:先执行一次循环体,再判断条件是否为真。如果条件为假,继续循环;如果条件为真,则退出循环。

这和 while 循环有本质区别。while 是“先判断,再执行”,而 repeat…until 是“先执行,再判断”。这个“至少执行一次”的特性,让 repeat…until 在处理用户输入、菜单选择等场景中特别实用。

形象比喻:想象你走进一家餐厅,服务员问你:“要点餐吗?” 你回答:“要!” 然后才开始点菜。这就是“先做,再判断”——和 repeat…until 的行为完全一致。


与 while 循环的对比分析

我们通过一个具体例子来对比 whilerepeat…until 的行为差异:

-- 示例 1:使用 while 循环
local count = 10
while count < 5 do
    print("count is:", count)
    count = count + 1
end
print("while 循环结束")

上面这段代码中,count 初始值为 10,条件 count < 5 一开始就为假。因此,while 循环体一次都没有执行,直接跳过。

再看 repeat…until 版本:

-- 示例 2:使用 repeat…until 循环
local count = 10
repeat
    print("count is:", count)
    count = count + 1
until count < 5
print("repeat…until 循环结束")

虽然 count 初始值为 10,但 repeat…until 依然会执行一次循环体,输出 count is: 10,然后判断 count < 5 是否为真。此时 count 已变为 11,条件为假,继续循环。直到某次 count 变成某个小于 5 的值(比如你手动改了逻辑),才会退出。

💡 关键区别repeat…until 保证至少执行一次,而 while 可能一次都不执行。


实际应用案例:用户输入验证

在开发交互式程序时,经常需要用户输入数据,比如输入年龄、密码等。我们要求用户输入一个合法的数字(比如 18 到 100 之间),如果输入无效,就要求重新输入。

repeat…until 来实现,非常自然:

-- 用户输入年龄验证
local age = 0

repeat
    print("请输入你的年龄(18 ~ 100):")
    local input = io.read()  -- 读取用户输入
    age = tonumber(input)    -- 尝试将输入转为数字

    -- 检查输入是否为有效数字,且在合理范围内
    if age == nil then
        print("❌ 输入无效,请输入一个数字!")
    elseif age < 18 or age > 100 then
        print("❌ 年龄必须在 18 到 100 之间!")
    else
        print("✅ 年龄输入成功:", age)
    end
until age >= 18 and age <= 100  -- 条件满足才退出循环

📌 代码说明

  • io.read() 是 Lua 中读取用户输入的函数,返回字符串。
  • tonumber() 尝试将字符串转为数字,若失败返回 nil
  • 循环会持续执行,直到用户输入一个有效的年龄值。
  • 因为使用了 repeat…until,我们无需担心“用户第一次输入就合法”而跳过提示的问题。

这个例子完美体现了 repeat…until 的优势:先让程序跑起来,再判断是否继续。


多重条件判断与逻辑组合

repeat…until 的条件表达式可以是复杂的逻辑组合,支持 andornot 等运算符。我们来看一个更复杂的例子:模拟一个“密码解锁”系统。

-- 模拟密码解锁系统
local password = "123456"
local attempts = 0
local max_attempts = 3
local is_unlocked = false

repeat
    print("请输入密码(最多尝试", max_attempts, "次):")
    local input = io.read()

    attempts = attempts + 1

    if input == password then
        is_unlocked = true
        print("🔓 解锁成功!")
    elseif attempts >= max_attempts then
        print("❌ 尝试次数已满,系统锁定。")
        break  -- 强制退出循环
    else
        local remaining = max_attempts - attempts
        print("❌ 密码错误,还剩", remaining, "次机会。")
    end
until is_unlocked

-- 外层逻辑判断
if not is_unlocked then
    print("系统已锁定,无法继续。")
end

📌 关键点说明

  • break 是 Lua 中用于立即退出循环的语句,可在 repeat…until 中使用。
  • 条件 until is_unlocked 只在成功输入密码时才为真,循环才会结束。
  • 即使尝试次数满,通过 break 也能提前退出,避免无意义的后续循环。

循环体中的变量作用域与初始化

repeat…until 循环中,循环体内的变量在每次迭代时都会重新创建(如果使用 local 声明)。这有助于防止变量污染。

例如:

-- 变量作用域示例
local i = 1

repeat
    local temp = i * 2  -- 每次循环都创建新的 temp 变量
    print("第", i, "次循环,temp = ", temp)
    i = i + 1
until i > 3

输出结果:

第 1 次循环,temp = 2
第 2 次循环,temp = 4
第 3 次循环,temp = 6

✅ 重点:temp 是局部变量,仅在当前循环体中有效,不会影响外部变量。


常见错误与最佳实践

错误 1:条件永远为假,导致无限循环

-- ❌ 错误示例:条件永远不会为真
local x = 5
repeat
    print("x =", x)
    x = x + 1
until x < 5  -- x 从 5 开始递增,永远不会小于 5

这个循环会无限执行下去,直到手动中断程序。

修复方法:确保条件表达式最终能变为真。

错误 2:忘记更新控制变量

-- ❌ 错误示例:变量未更新
repeat
    print("Hello")
until true  -- 条件永远为真,但循环体不改变任何状态

虽然条件是 true,但 repeat…until 会执行一次后就退出,不会无限循环。但如果你写成 until false,就会无限循环。

建议:每次循环体中都要确保条件变量发生变化。


总结与建议

Lua repeat…until 循环 是一个强大且容易被忽视的控制结构。它特别适合那些“必须至少执行一次”的场景,比如用户交互、状态检测、初始化流程等。

相比 while,它更安全——不会因为初始条件不满足而跳过关键逻辑。相比 for,它更灵活——可以基于动态条件控制循环次数。

在实际开发中,建议你:

  • 当你需要“先做再判断”时,优先考虑 repeat…until
  • 在处理用户输入、配置校验时,它几乎是首选
  • 注意避免无限循环,确保条件变量在循环中被正确更新

结语

掌握 Lua repeat…until 循环,意味着你对程序流程控制的理解又深了一层。它不是“炫技”的语法,而是解决真实问题的实用工具。

无论你是初学者还是中级开发者,只要你在写交互式脚本、小游戏、配置程序,这个循环都能帮你写出更健壮、更清晰的代码。

不妨现在就打开 Lua 编辑器,动手试一试这几个例子。代码写得越多,理解就越深。祝你编程愉快!