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 循环的奥秘。
一、循环的“守门人”:while
和 repeat-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 循环如同编程中的“重复引擎”,通过 while
、repeat-until
、for
等结构,开发者可以灵活控制程序的执行流程。从基础循环到嵌套、控制语句,再到性能优化,掌握这些技巧能显著提升代码的效率与可读性。
对于编程新手,建议从简单案例入手,逐步尝试嵌套与控制逻辑;中级开发者则可深入探索泛型循环与性能优化的细节。记住:实践是掌握循环的唯一捷径。不妨现在就打开你的编辑器,用 Lua 循环解决一个真实问题吧!