Lua流程控制
概述
流程控制是编程语言的核心特性,Lua提供了条件语句、循环语句和跳转语句来控制程序的执行流程。
1. 条件语句
1.1 if语句
最基本的条件语句,用于根据条件执行不同的代码块。
lua
-- 基本if语句
local score = 85
if score >= 60 then
print("及格")
end
-- if-else语句
local age = 18
if age >= 18 then
print("成年人")
else
print("未成年人")
end
-- if-elseif-else语句
local grade = 85
if grade >= 90 then
print("优秀")
elseif grade >= 80 then
print("良好")
elseif grade >= 70 then
print("中等")
elseif grade >= 60 then
print("及格")
else
print("不及格")
end1.2 条件表达式
在Lua中,只有nil和false被认为是假值,其他所有值都是真值。
lua
-- 数字0是真值
if 0 then
print("0是真值") -- 会执行
end
-- 空字符串是真值
if "" then
print("空字符串是真值") -- 会执行
end
-- 空表是真值
if {} then
print("空表是真值") -- 会执行
end
-- nil和false是假值
if nil then
print("这不会执行")
end
if false then
print("这也不会执行")
end1.3 复杂条件
lua
local username = "admin"
local password = "123456"
local is_active = true
-- 使用逻辑运算符组合条件
if username == "admin" and password == "123456" and is_active then
print("登录成功")
elseif not is_active then
print("账户已被禁用")
else
print("用户名或密码错误")
end
-- 使用括号明确优先级
local a, b, c = 10, 20, 30
if (a > b) or (b > c and a > c) then
print("复杂条件满足")
end2. 循环语句
2.1 while循环
当条件为真时重复执行代码块。
lua
-- 基本while循环
local i = 1
while i <= 5 do
print("第" .. i .. "次循环")
i = i + 1
end
-- 无限循环(需要break跳出)
local count = 0
while true do
count = count + 1
print("计数:", count)
if count >= 3 then
break -- 跳出循环
end
end
-- 条件循环
local input = ""
while input ~= "quit" do
print("请输入命令 (输入quit退出):")
-- input = io.read() -- 实际应用中读取用户输入
input = "quit" -- 示例中直接设置退出条件
end2.2 repeat-until循环
至少执行一次,然后检查条件。
lua
-- 基本repeat-until循环
local num = 1
repeat
print("数字:", num)
num = num + 1
until num > 5
-- 菜单循环示例
local choice
repeat
print("1. 选项一")
print("2. 选项二")
print("3. 退出")
print("请选择:")
-- choice = tonumber(io.read()) -- 实际应用中读取用户输入
choice = 3 -- 示例中直接设置退出条件
if choice == 1 then
print("执行选项一")
elseif choice == 2 then
print("执行选项二")
elseif choice == 3 then
print("退出程序")
else
print("无效选择")
end
until choice == 32.3 for循环
数值for循环
lua
-- 基本数值for循环
for i = 1, 5 do
print("i =", i)
end
-- 输出: 1, 2, 3, 4, 5
-- 指定步长
for i = 1, 10, 2 do
print("奇数:", i)
end
-- 输出: 1, 3, 5, 7, 9
-- 递减循环
for i = 5, 1, -1 do
print("倒计时:", i)
end
-- 输出: 5, 4, 3, 2, 1
-- 浮点数循环
for i = 0, 1, 0.1 do
print(string.format("%.1f", i))
end泛型for循环
lua
-- 遍历数组
local fruits = {"apple", "banana", "orange", "grape"}
-- 使用ipairs遍历数组(推荐)
for index, value in ipairs(fruits) do
print(index, value)
end
-- 遍历表的所有键值对
local person = {
name = "Alice",
age = 30,
city = "Beijing"
}
-- 使用pairs遍历所有键值对
for key, value in pairs(person) do
print(key, value)
end
-- 遍历字符串的每一行
local text = "第一行\n第二行\n第三行"
for line in string.gmatch(text, "[^\n]+") do
print("行内容:", line)
end2.4 嵌套循环
lua
-- 九九乘法表
for i = 1, 9 do
for j = 1, i do
io.write(j .. "x" .. i .. "=" .. (i*j) .. "\t")
end
print() -- 换行
end
-- 二维数组遍历
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
print()
end3. 跳转语句
3.1 break语句
用于跳出当前循环。
lua
-- 在while循环中使用break
local i = 1
while true do
if i > 5 then
break -- 跳出循环
end
print("i =", i)
i = i + 1
end
-- 在for循环中使用break
for i = 1, 10 do
if i == 6 then
break -- 当i等于6时跳出循环
end
print(i)
end
-- 输出: 1, 2, 3, 4, 5
-- 在嵌套循环中,break只跳出最内层循环
for i = 1, 3 do
print("外层循环:", i)
for j = 1, 5 do
if j == 3 then
break -- 只跳出内层循环
end
print(" 内层循环:", j)
end
end3.2 goto语句(Lua 5.2+)
用于无条件跳转到标签位置。
lua
-- 基本goto用法
local x = 10
if x > 5 then
goto skip_block
end
print("这行不会执行")
::skip_block::
print("跳转到这里")
-- 使用goto跳出嵌套循环
for i = 1, 5 do
for j = 1, 5 do
if i * j > 10 then
goto exit_loops -- 跳出所有循环
end
print(i, j, i * j)
end
end
::exit_loops::
print("跳出嵌套循环")
-- goto的限制示例
local function demo_goto_limits()
local x = 1
if x == 1 then
-- goto cannot_reach -- 错误:不能跳转到不同的块
end
do
::cannot_reach::
print("这是一个标签")
end
end4. 实际应用示例
4.1 输入验证
lua
local function get_valid_number(prompt, min, max)
local num
repeat
print(prompt)
-- num = tonumber(io.read()) -- 实际应用中读取输入
num = 50 -- 示例值
if not num then
print("请输入一个有效的数字")
elseif num < min or num > max then
print(string.format("数字必须在%d到%d之间", min, max))
end
until num and num >= min and num <= max
return num
end
-- 使用示例
-- local age = get_valid_number("请输入年龄 (1-120):", 1, 120)4.2 菜单系统
lua
local function show_menu()
local menu_items = {
"1. 新建文件",
"2. 打开文件",
"3. 保存文件",
"4. 退出程序"
}
for _, item in ipairs(menu_items) do
print(item)
end
end
local function handle_menu()
local choice
repeat
show_menu()
print("请选择操作:")
-- choice = tonumber(io.read()) -- 实际应用中读取输入
choice = 4 -- 示例中直接退出
if choice == 1 then
print("新建文件...")
elseif choice == 2 then
print("打开文件...")
elseif choice == 3 then
print("保存文件...")
elseif choice == 4 then
print("退出程序")
else
print("无效选择,请重新输入")
end
until choice == 4
end
-- handle_menu()4.3 数据处理
lua
-- 统计数组中的正数、负数和零的个数
local function count_numbers(numbers)
local positive, negative, zero = 0, 0, 0
for _, num in ipairs(numbers) do
if num > 0 then
positive = positive + 1
elseif num < 0 then
negative = negative + 1
else
zero = zero + 1
end
end
return positive, negative, zero
end
local data = {1, -2, 0, 5, -3, 0, 7, -1}
local pos, neg, zero = count_numbers(data)
print(string.format("正数: %d, 负数: %d, 零: %d", pos, neg, zero))4.4 查找算法
lua
-- 线性查找
local function linear_search(array, target)
for i, value in ipairs(array) do
if value == target then
return i -- 返回索引
end
end
return nil -- 未找到
end
-- 二分查找(假设数组已排序)
local function binary_search(array, target)
local left, right = 1, #array
while left <= right do
local mid = math.floor((left + right) / 2)
if array[mid] == target then
return mid
elseif array[mid] < target then
left = mid + 1
else
right = mid - 1
end
end
return nil -- 未找到
end
-- 测试查找算法
local sorted_array = {1, 3, 5, 7, 9, 11, 13, 15}
local target = 7
local linear_result = linear_search(sorted_array, target)
local binary_result = binary_search(sorted_array, target)
print("线性查找结果:", linear_result) -- 4
print("二分查找结果:", binary_result) -- 45. 性能优化技巧
5.1 循环优化
lua
-- 避免在循环中重复计算
local array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
-- 不好的做法
for i = 1, #array do -- 每次都计算#array
print(array[i])
end
-- 好的做法
local len = #array
for i = 1, len do
print(array[i])
end
-- 或者使用ipairs
for i, v in ipairs(array) do
print(v)
end5.2 条件优化
lua
-- 将最可能的条件放在前面
local function process_grade(grade)
-- 假设大部分学生都是及格的
if grade >= 60 and grade < 70 then
return "及格"
elseif grade >= 70 and grade < 80 then
return "中等"
elseif grade >= 80 and grade < 90 then
return "良好"
elseif grade >= 90 then
return "优秀"
else
return "不及格"
end
end6. 常见陷阱和注意事项
6.1 循环变量作用域
lua
-- 循环变量的作用域仅在循环内
for i = 1, 3 do
print(i)
end
-- print(i) -- 错误:i在此处不可访问
-- 如果需要在循环外使用,需要预先声明
local i
for i = 1, 3 do
print(i)
end
print("最后的i值:", i) -- 36.2 浮点数循环
lua
-- 浮点数精度问题
for i = 0, 1, 0.1 do
print(i)
end
-- 可能不会精确输出0.1, 0.2, 0.3...
-- 更好的做法
for i = 0, 10 do
local val = i / 10
print(val)
end6.3 修改正在遍历的表
lua
local t = {1, 2, 3, 4, 5}
-- 危险:在遍历时修改表
for i, v in ipairs(t) do
if v % 2 == 0 then
table.remove(t, i) -- 可能导致跳过元素
end
end
-- 安全的做法:反向遍历
for i = #t, 1, -1 do
if t[i] % 2 == 0 then
table.remove(t, i)
end
end总结
Lua的流程控制语句简洁而强大:
- 条件语句:
if-then-else支持复杂的条件判断 - 循环语句:
while、repeat-until、for满足不同的循环需求 - 跳转语句:
break和goto提供灵活的控制流 - 泛型for循环:配合迭代器实现强大的遍历功能
掌握这些控制结构是编写高效Lua程序的基础,合理使用它们可以让代码更加清晰和高效。