循环语句 #
一、while 循环 #
1.1 基本 while 循环 #
lua
-- 基本语法
while condition do
-- 循环体
end
-- 示例:计数
local i = 1
while i <= 5 do
print(i)
i = i + 1
end
-- 输出:1 2 3 4 5
1.2 while 循环应用 #
lua
-- 求和
local sum = 0
local i = 1
while i <= 100 do
sum = sum + i
i = i + 1
end
print("1到100的和:" .. sum) -- 5050
-- 读取输入直到特定值
local input
while input ~= "quit" do
io.write("请输入(输入 quit 退出):")
input = io.read()
if input ~= "quit" then
print("你输入了:" .. input)
end
end
-- 处理队列
local queue = {1, 2, 3, 4, 5}
while #queue > 0 do
local item = table.remove(queue, 1)
print("处理:" .. item)
end
1.3 无限循环 #
lua
-- 无限循环
while true do
-- 需要使用 break 退出
local input = io.read()
if input == "exit" then
break
end
print("处理:" .. input)
end
二、repeat-until 循环 #
2.1 基本 repeat-until 循环 #
lua
-- 基本语法
repeat
-- 循环体
until condition
-- 示例:至少执行一次
local i = 1
repeat
print(i)
i = i + 1
until i > 5
-- 输出:1 2 3 4 5
2.2 repeat-until 与 while 的区别 #
lua
-- while:先判断后执行
local x = 10
while x < 5 do
print(x) -- 不会执行
end
-- repeat-until:先执行后判断
local y = 10
repeat
print(y) -- 执行一次,输出 10
until y >= 5
2.3 repeat-until 应用 #
lua
-- 猜数字游戏
local target = math.random(1, 100)
local guess
repeat
io.write("猜一个数字(1-100):")
guess = tonumber(io.read())
if guess == nil then
print("请输入有效数字")
elseif guess < target then
print("太小了!")
elseif guess > target then
print("太大了!")
end
until guess == target
print("恭喜,猜对了!")
三、数值 for 循环 #
3.1 基本数值 for 循环 #
lua
-- 基本语法
for var = start, stop, step do
-- 循环体
end
-- 示例:从 1 到 5
for i = 1, 5 do
print(i)
end
-- 输出:1 2 3 4 5
-- 指定步长
for i = 1, 10, 2 do
print(i)
end
-- 输出:1 3 5 7 9
-- 负步长
for i = 10, 1, -1 do
print(i)
end
-- 输出:10 9 8 7 6 5 4 3 2 1
3.2 for 循环变量作用域 #
lua
-- 循环变量是局部变量
for i = 1, 5 do
print(i)
end
-- print(i) -- 错误:i 不可见
-- 循环前定义变量
local i
for i = 1, 5 do
print(i)
end
print(i) -- nil(循环内的 i 是新变量)
3.3 数值 for 应用 #
lua
-- 计算阶乘
local function factorial(n)
local result = 1
for i = 1, n do
result = result * i
end
return result
end
print(factorial(5)) -- 120
-- 打印乘法表
for i = 1, 9 do
for j = 1, i do
io.write(string.format("%d×%d=%d\t", j, i, i * j))
end
io.write("\n")
end
-- 遍历数组
local arr = {10, 20, 30, 40, 50}
for i = 1, #arr do
print(string.format("arr[%d] = %d", i, arr[i]))
end
四、泛型 for 循环 #
4.1 ipairs 迭代器 #
lua
-- ipairs:遍历数组部分
local arr = {"a", "b", "c", "d", "e"}
for i, v in ipairs(arr) do
print(i, v)
end
-- 输出:
-- 1 a
-- 2 b
-- 3 c
-- 4 d
-- 5 e
-- 注意:ipairs 遇到 nil 会停止
local sparse = {1, 2, nil, 4}
for i, v in ipairs(sparse) do
print(i, v)
end
-- 只输出:1 1 和 2 2
4.2 pairs 迭代器 #
lua
-- pairs:遍历所有键值对
local dict = {
name = "Lua",
version = 5.4,
author = "PUC-Rio"
}
for k, v in pairs(dict) do
print(k, v)
end
-- 输出顺序不确定
-- pairs 可以遍历 nil 值之后的元素
local t = {1, 2, nil, 4}
for k, v in pairs(t) do
print(k, v)
end
-- 输出:1 1, 2 2, 4 4
4.3 字符串迭代 #
lua
-- string.gmatch 迭代字符串
local s = "hello world from lua"
for word in string.gmatch(s, "%a+") do
print(word)
end
-- 输出:hello, world, from, lua
-- 遍历字符
for i = 1, #s do
local c = string.sub(s, i, i)
print(i, c)
end
4.4 文件迭代 #
lua
-- 逐行读取文件
local file = io.open("data.txt", "r")
if file then
for line in file:lines() do
print(line)
end
file:close()
end
五、循环控制 #
5.1 break 语句 #
lua
-- break:跳出循环
for i = 1, 10 do
if i == 5 then
break
end
print(i)
end
-- 输出:1 2 3 4
-- 查找元素
local arr = {3, 5, 2, 8, 1, 9}
local target = 8
local found_index = nil
for i, v in ipairs(arr) do
if v == target then
found_index = i
break
end
end
if found_index then
print("找到 " .. target .. " 在位置 " .. found_index)
end
5.2 goto 语句(Lua 5.2+) #
lua
-- goto:跳转到标签
local i = 0
::loop::
i = i + 1
print(i)
if i < 5 then
goto loop
end
-- 输出:1 2 3 4 5
-- 使用 goto 模拟 continue
for i = 1, 10 do
if i % 2 == 0 then
goto continue
end
print(i) -- 只打印奇数
::continue::
end
-- 使用 goto 跳出嵌套循环
for i = 1, 10 do
for j = 1, 10 do
if i + j > 15 then
goto done
end
print(i, j)
end
end
::done::
print("完成")
5.3 没有 continue? #
Lua 没有内置的 continue,但有几种替代方案:
lua
-- 方法1:使用 goto(Lua 5.2+)
for i = 1, 10 do
if i % 2 == 0 then
goto continue
end
print(i)
::continue::
end
-- 方法2:使用 if-else
for i = 1, 10 do
if i % 2 ~= 0 then
print(i)
end
end
-- 方法3:使用 while 模拟
local i = 0
while i < 10 do
i = i + 1
if i % 2 == 0 then
-- continue
else
print(i)
end
end
六、嵌套循环 #
6.1 基本嵌套 #
lua
-- 打印矩形
for i = 1, 3 do
for j = 1, 5 do
io.write("* ")
end
io.write("\n")
end
-- 输出:
-- * * * * *
-- * * * * *
-- * * * * *
-- 打印三角形
for i = 1, 5 do
for j = 1, i do
io.write("* ")
end
io.write("\n")
end
-- 输出:
-- *
-- * *
-- * * *
-- * * * *
-- * * * * *
6.2 嵌套循环应用 #
lua
-- 二维数组遍历
local matrix = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
}
for i = 1, #matrix do
for j = 1, #matrix[i] do
io.write(matrix[i][j] .. " ")
end
io.write("\n")
end
-- 查找二维数组
local function find_in_matrix(matrix, target)
for i = 1, #matrix do
for j = 1, #matrix[i] do
if matrix[i][j] == target then
return i, j
end
end
end
return nil, nil
end
-- 冒泡排序
local function bubble_sort(arr)
local n = #arr
for i = 1, n - 1 do
for j = 1, n - i do
if arr[j] > arr[j + 1] then
arr[j], arr[j + 1] = arr[j + 1], arr[j]
end
end
end
return arr
end
七、自定义迭代器 #
7.1 简单迭代器 #
lua
-- 创建一个简单的迭代器
local function iter(t)
local i = 0
local n = #t
return function()
i = i + 1
if i <= n then
return t[i]
end
end
end
-- 使用
local arr = {1, 2, 3, 4, 5}
for v in iter(arr) do
print(v)
end
7.2 状态迭代器 #
lua
-- 带状态的迭代器
local function range_iter(t, current)
current = current + 1
if current <= t.stop then
return current
end
end
local function range(start, stop)
return range_iter, {start = start, stop = stop}, start - 1
end
-- 使用
for i in range(1, 5) do
print(i)
end
7.3 实用迭代器 #
lua
-- 反向迭代器
local function rev_iter(t, i)
i = i - 1
if i >= 1 then
return i, t[i]
end
end
local function reversed(t)
return rev_iter, t, #t + 1
end
local arr = {1, 2, 3, 4, 5}
for i, v in reversed(arr) do
print(i, v)
end
-- 键排序迭代器
local function sorted_pairs(t)
local keys = {}
for k in pairs(t) do
table.insert(keys, k)
end
table.sort(keys)
local i = 0
return function()
i = i + 1
local k = keys[i]
if k then
return k, t[k]
end
end
end
local dict = {c = 3, a = 1, b = 2}
for k, v in sorted_pairs(dict) do
print(k, v)
end
八、性能优化 #
8.1 减少循环内计算 #
lua
-- 不推荐:循环内重复计算
for i = 1, #arr do
if i <= #arr / 2 then
process(arr[i])
end
end
-- 推荐:预先计算
local half = #arr / 2
for i = 1, #arr do
if i <= half then
process(arr[i])
end
end
8.2 选择合适的迭代器 #
lua
-- 数组遍历:使用数值 for(最快)
for i = 1, #arr do
process(arr[i])
end
-- 需要值时:使用 ipairs
for i, v in ipairs(arr) do
process(v)
end
-- 字典遍历:使用 pairs
for k, v in pairs(dict) do
process(k, v)
end
九、实用示例 #
9.1 斐波那契数列 #
lua
local function fibonacci(n)
local a, b = 0, 1
for i = 1, n do
print(a)
a, b = b, a + b
end
end
fibonacci(10)
9.2 质数判断 #
lua
local function is_prime(n)
if n < 2 then return false end
if n == 2 then return true end
if n % 2 == 0 then return false end
for i = 3, math.sqrt(n), 2 do
if n % i == 0 then
return false
end
end
return true
end
-- 打印 100 以内的质数
for i = 1, 100 do
if is_prime(i) then
io.write(i .. " ")
end
end
9.3 数据处理 #
lua
-- 统计单词频率
local function word_frequency(text)
local freq = {}
for word in string.gmatch(text:lower(), "%a+") do
freq[word] = (freq[word] or 0) + 1
end
return freq
end
local text = "hello world hello lua world world"
local freq = word_frequency(text)
for word, count in pairs(freq) do
print(word, count)
end
十、总结 #
本章介绍了 Lua 的循环语句:
- while 循环:先判断后执行
- repeat-until 循环:先执行后判断,至少执行一次
- 数值 for 循环:按步长遍历数值范围
- 泛型 for 循环:使用迭代器遍历
- 循环控制:break 跳出循环,goto 跳转
- 嵌套循环:处理多维数据
- 自定义迭代器:创建自己的迭代器
掌握循环语句是处理重复任务的基础。下一章,我们将学习函数。
最后更新:2026-03-27