Lua 循环(手把手讲解)

更新时间:

💡一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

  • 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...点击查看项目介绍 ;
  • 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;

截止目前, 星球 内专栏累计输出 82w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 2900+ 小伙伴加入学习 ,欢迎点击围观

前言

在编程的世界中,循环如同音乐中的重复旋律,是构建程序逻辑的核心工具之一。无论是处理大量数据、执行重复性任务,还是实现复杂的算法,Lua 循环都是开发者不可或缺的“瑞士军刀”。Lua 语言凭借其简洁优雅的语法,为循环机制提供了多种实现方式,既适合编程新手快速上手,也能满足中级开发者对灵活性与效率的需求。本文将从基础到进阶,结合生动的比喻与实际案例,带你全面理解 Lua 循环的奥秘。


一、循环的“守门人”:whilerepeat-until

1.1 while 循环:条件为王

while 循环的运作逻辑如同一位严格的“守门人”——只有当条件为 true 时,才会允许循环体内的代码执行。其语法结构如下:

while 条件 do  
    -- 循环体  
end  

案例 1:计算 1 到 10 的和:

local sum = 0  
local i = 1  
while i <= 10 do  
    sum = sum + i  
    i = i + 1  
end  
print("总和为:" .. sum)  -- 输出:总和为:55  

关键点while 的条件判断发生在循环体执行之前。若初始条件不满足,循环体将一次都不会执行。

1.2 repeat-until 循环:先执行,再检查

while 相反,repeat-until 循环更像是“先尝试开门,再检查钥匙是否匹配”的逻辑。它确保循环体至少执行一次,语法如下:

repeat  
    -- 循环体  
until 条件  

案例 2:猜数字游戏(至少执行一次):

local target = 42  
local guess  
repeat  
    print("猜一个 1-100 的数字:")  
    guess = tonumber(io.read()) or 0  
    if guess > target then  
        print("太大了!")  
    elseif guess < target then  
        print("太小了!")  
    end  
until guess == target  
print("恭喜你,猜对了!")  

关键点repeat-until 的条件判断在循环体之后,因此即使初始条件为 true,循环体仍会执行一次。


二、数值与泛型的“旅行者”:for 循环

2.1 标准 for 循环:数值范围的优雅遍历

Lua 的 for 循环专为数值迭代设计,语法简洁直观:

for 变量 = 初始值, 终止值, 步长 do  
    -- 循环体  
end  

默认步长为 1,若需逆向遍历,可设置负数步长。

案例 3:倒计时程序:

for i = 10, 1, -1 do  
    print(i)  
    os.execute("sleep 1")  -- 假设系统支持 sleep 命令  
end  
print("发射!")  

2.2 泛型 for 循环:表与字符串的遍历大师

当需要遍历表、字符串或用户自定义数据结构时,泛型 for 循环(以 in 关键字开头)展现了其强大之处:

for 变量1, 变量2, ... in 可迭代对象 do  
    -- 循环体  
end  

案例 4:遍历表格的键值对:

local person = {name = "Alice", age = 30, city = "Beijing"}  
for key, value in pairs(person) do  
    print(key .. " = " .. value)  
end  
-- 输出:  
-- name = Alice  
-- age = 30  
-- city = Beijing  

关键点pairs() 函数用于遍历表的所有键值对,而 ipairs() 则针对数值索引的数组部分。


三、嵌套循环:俄罗斯套娃的逻辑之美

当多个循环相互嵌套时,它们会形成类似“俄罗斯套娃”的分层结构。例如,外层循环控制行,内层循环控制列,常用于处理二维数据或生成复杂模式。

案例 5:打印乘法表:

for i = 1, 9 do  
    for j = 1, i do  
        io.write(j .. "×" .. i .. "=" .. i*j .. "\t")  
    end  
    print()  -- 换行  
end  

此案例中,外层循环 i 控制行数,内层循环 j 控制每行的列数,最终输出经典的九九乘法表。


四、循环控制:灵活的“紧急出口”与“传送门”

4.1 break:提前终止循环

当遇到特定条件时,break 语句如同按下“紧急停止”按钮,立即跳出当前循环。

案例 6:查找列表中的元素:

local fruits = {"apple", "banana", "orange", "grape"}  
for index, fruit in ipairs(fruits) do  
    if fruit == "orange" then  
        print("找到橘子,位置:" .. index)  
        break  
    end  
end  

4.2 goto:跳转的“传送门”(慎用)

Lua 支持 goto 标签跳转,但需谨慎使用,因其可能破坏代码结构。

案例 7:跳转至循环外的标签:

for i = 1, 5 do  
    for j = 1, 5 do  
        if i * j > 10 then  
            goto end_loop  -- 跳出所有循环  
        end  
        print(i.."×"..j.."="..i*j)  
    end  
end  
::end_loop::  

五、性能优化:让循环“减负”

5.1 避免循环内重复计算

将循环内的计算移到循环外,可显著提升效率。例如:

local max = 1000000  
local result = 0  
local factor = 2.5  -- 提前计算常量  
for i = 1, max do  
    result = result + (i * factor)  -- 避免每次循环计算 2.5*i  
end  

5.2 提前终止循环

若目标在循环中途达成,应尽早使用 break,减少无意义的迭代。

5.3 减少函数调用

将函数调用移到循环外,或改用局部变量暂存结果,例如:

local math_sin = math.sin  -- 局部引用  
local sum = 0  
for i = 1, 1000 do  
    sum = sum + math_sin(i)  -- 避免每次循环查找全局 math.sin  
end  

六、实战案例:斐波那契数列生成

问题:生成前 20 项斐波那契数列,要求输出格式为“第 N 项:数值”。

解决方案

local a, b = 0, 1  
for i = 1, 20 do  
    print("第 " .. i .. " 项:" .. b)  
    a, b = b, a + b  -- 同时更新 a 和 b  
end  

此案例通过 for 循环与元组赋值语法,高效实现了数列的迭代。


结论

Lua 循环如同编程中的“重复引擎”,通过 whilerepeat-untilfor 等结构,开发者可以灵活控制程序的执行流程。从基础循环到嵌套、控制语句,再到性能优化,掌握这些技巧能显著提升代码的效率与可读性。

对于编程新手,建议从简单案例入手,逐步尝试嵌套与控制逻辑;中级开发者则可深入探索泛型循环与性能优化的细节。记住:实践是掌握循环的唯一捷径。不妨现在就打开你的编辑器,用 Lua 循环解决一个真实问题吧!

最新发布