第三章:流程控制

掌握了基础语法和数据类型后,我们需要学习如何控制程序的执行流程。Lua 提供了传统的条件语句和循环结构,但其语法与其他语言略有不同,更加简洁明了。

本章将详细讲解 if 条件判断、while 循环、for 循环(数值型和泛型)以及 repeat-until 循环。

3.1 条件语句

if 语句

if 语句用于根据条件执行代码块。

local age = 20

if age >= 18 then
    print("成年人")
end

if-else 语句

如果条件为假,执行 else 块。

local age = 15

if age >= 18 then
    print("成年人")
else
    print("未成年人")
end

if-elseif-else 语句

处理多重条件。注意关键字是 elseif(中间没有空格)。

local score = 85

if score >= 90 then
    print("优秀")
elseif score >= 80 then
    print("良好")
elseif score >= 60 then
    print("及格")
else
    print("不及格")
end

提示:Lua 中没有 switch 语句,通常使用 if-elseif 或表(Table)来替代。

3.2 循环语句

while 循环

while 循环在条件为真时重复执行代码块。

local i = 1
while i <= 5 do
    print(i)
    i = i + 1
end

repeat-until 循环

repeat-until 类似于其他语言的 do-while 循环。代码块至少执行一次,直到条件为真时停止
注意:条件判断是在循环体执行之后进行的。

local x = 10
repeat
    print(x)
    x = x - 1
until x == 0

for 循环

Lua 有两种 for 循环:数值 for 和泛型 for

数值 for 循环

语法:for var = start, end, step do ... end

  • var: 循环变量,自动声明为局部变量。

  • start: 起始值。

  • end: 终止值(包含)。

  • step: 步长(可选,默认为 1)。

-- 从 1 数到 10
for i = 1, 10 do
    print(i)
end

-- 从 10 倒数到 1,步长为 -1
for i = 10, 1, -1 do
    print(i)
end

-- 指定步长
for i = 1, 10, 2 do
    print(i) -- 1, 3, 5, 7, 9
end

泛型 for 循环

泛型 for 循环通过迭代器函数来遍历集合。最常用的是 ipairs(用于数组)和 pairs(用于表)。

遍历数组

local fruits = {"Apple", "Banana", "Orange"}

for i, v in ipairs(fruits) do
    print(i, v)
end

遍历表(字典)

local user = {name = "John", age = 25}

for k, v in pairs(user) do
    print(k, v)
end

循环控制

  • break: 立即跳出当前循环(for, while, repeat)。

  • return: 从函数返回结果(如果在循环中使用,会结束函数执行,也就自然结束了循环)。

  • 注意:Lua 5.1 及更早版本没有 continue 语句(跳过本次循环)。但在 Lua 5.2+ 中可以使用 goto 模拟,或者使用 if 条件包裹循环体来实现类似效果。

使用 break

for i = 1, 10 do
    if i == 5 then
        break
    end
    print(i)
end
-- 输出: 1 2 3 4

3.3 流程控制最佳实践

避免无限循环

在使用 whilerepeat 循环时,务必确保循环条件最终会变为假(while)或真(until),否则会导致程序卡死。

循环性能优化

  • for 循环中,循环变量是局部的,这很好。

  • 如果循环次数非常多,尽量避免在循环体内创建新的表或闭包,这会增加垃圾回收的压力。

  • 对于数值 for 循环,它的 start, end, step 表达式只会在循环开始前计算一次。

替代 switch 语句

虽然 Lua 没有 switch,但利用表可以写出更优雅的代码。

-- 传统写法
if action == "start" then
    start()
elseif action == "stop" then
    stop()
elseif action == "pause" then
    pause()
end

-- 表驱动写法 (更加清晰和易扩展)
local actions = {
    start = start,
    stop = stop,
    pause = pause
}

if actions[action] then
    actions[action]()
else
    print("Invalid action")
end

练习题

  1. 使用 for 循环计算 1 到 100 的总和。

  2. 使用 while 循环打印 1 到 10 之间的所有偶数。

  3. 创建一个包含若干数字的数组,使用泛型 for 循环找出其中的最大值。

  4. 编写一个程序,判断一个年份是否为闰年(能被 4 整除但不能被 100 整除,或者能被 400 整除)。


下一章预告:函数是 Lua 中非常重要的概念。下一章我们将深入探讨函数的定义、多返回值、变长参数以及闭包等高级特性。