Lua


4. 控制结构


文档摘要

控制结构 Lua语言控制结构详解:代码实践与深度解析 引言 程序设计的核心在于控制程序的执行流程。控制结构正是编程语言中实现这种控制的关键工具。它们决定了代码执行的顺序、条件分支以及循环迭代,是构建逻辑复杂、功能丰富的应用程序的基础。Lua语言以其简洁、高效和易于嵌入而著称,其控制结构同样体现了这些特点,既清晰易懂又功能完备。 一、条件语句:逻辑分支的基石 条件语句允许程序根据不同的条件执行不同的代码块,是实现程序逻辑分支的关键。Lua提供了 结构来实现条件判断。 1. 结构:单条件执行 最基本的条件语句是 结构,它仅在条件为真时执行相应的代码块。 语法: 代码实践 1:判断数字正负 内容详解: 关键字标志着条件语句的开始。 是一个返回布尔值的表达式。

4. 控制结构

Lua语言控制结构详解:代码实践与深度解析

引言

程序设计的核心在于控制程序的执行流程。控制结构正是编程语言中实现这种控制的关键工具。它们决定了代码执行的顺序、条件分支以及循环迭代,是构建逻辑复杂、功能丰富的应用程序的基础。Lua语言以其简洁、高效和易于嵌入而著称,其控制结构同样体现了这些特点,既清晰易懂又功能完备。

一、条件语句:逻辑分支的基石

条件语句允许程序根据不同的条件执行不同的代码块,是实现程序逻辑分支的关键。Lua提供了 if-then-else 结构来实现条件判断。

1. if-then-end 结构:单条件执行

最基本的条件语句是 if-then-end 结构,它仅在条件为真时执行相应的代码块。

语法:

if 条件表达式 then -- 条件为真时执行的代码块 end

代码实践 1:判断数字正负

local number = 10 if number > 0 then print("数字是正数") end number = -5 if number > 0 then print("数字是正数") -- 此代码块不会执行,因为条件为假 end

内容详解:

  • if 关键字标志着条件语句的开始。

  • 条件表达式 是一个返回布尔值的表达式。在Lua中,除了 falsenil 被视为假,其他所有值(包括数字0和空字符串)都被视为真。

  • then 关键字分隔条件表达式和代码块。

  • 代码块是条件为真时要执行的一系列Lua语句。

  • end 关键字标志着 if 语句的结束。

2. if-then-else-end 结构:双分支选择

if-then-else-end 结构提供了在条件为真和条件为假时分别执行不同代码块的能力。

语法:

if 条件表达式 then -- 条件为真时执行的代码块 else -- 条件为假时执行的代码块 end

代码实践 2:判断奇偶数

local number = 7 if number % 2 == 0 then print("数字是偶数") else print("数字是奇数") end

内容详解:

  • else 关键字在 then 代码块之后,标志着条件为假时执行的代码块的开始。

  • else 代码块中的语句会在条件表达式为假 (falsenil) 时执行。

3. if-then-elseif-then-else-end 结构:多分支选择

当需要根据多个互斥条件进行选择时,可以使用 if-then-elseif-then-else-end 结构。elseif 可以有多个,用于检查多个不同的条件。

语法:

if 条件表达式1 then -- 条件表达式1为真时执行的代码块 elseif 条件表达式2 then -- 条件表达式1为假且条件表达式2为真时执行的代码块 elseif 条件表达式3 then -- 条件表达式1和2为假且条件表达式3为真时执行的代码块 -- ... 可以有多个 elseif else -- 所有条件表达式都为假时执行的代码块 end

代码实践 3:成绩等级判断

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

内容详解:

  • elseif 关键字用于添加额外的条件判断分支。它可以重复多次,每个 elseif 后都跟随一个条件表达式和一个 then 代码块。

  • 条件表达式会从上到下依次求值。一旦某个条件表达式为真,其对应的 then 代码块就会被执行,并且后续的 elseifelse 分支将被跳过。

  • 如果所有 ifelseif 的条件表达式都为假,则会执行 else 代码块(如果存在 else 分支)。

4. 嵌套 if 语句:更复杂的逻辑

if 语句可以嵌套在另一个 if 语句的代码块中,以实现更复杂的条件逻辑。

代码实践 4:判断闰年

local year = 2024 if year % 4 == 0 then if year % 100 == 0 then if year % 400 == 0 then print(year .. "年是闰年") else print(year .. "年不是闰年") end else print(year .. "年是闰年") end else print(year .. "年不是闰年") end

内容详解:

  • 嵌套 if 语句允许在满足一个条件的基础上,进一步判断其他条件。

  • 嵌套层级不宜过深,过深的嵌套会降低代码的可读性和维护性。通常可以使用逻辑运算符 (and, or, not) 来简化复杂的条件表达式,减少嵌套层级。

二、循环语句:重复执行的利器

循环语句允许程序重复执行一段代码块,直到满足特定条件为止。Lua提供了三种主要的循环结构:while 循环、for 循环和 repeat-until 循环。

1. while 循环:前置条件循环

while 循环在每次循环迭代之前检查条件表达式,只有当条件为真时才执行循环体。

语法:

while 条件表达式 do -- 循环体代码 end

代码实践 5:计算阶乘

local n = 5 local factorial = 1 local i = 1 while i <= n do factorial = factorial * i i = i + 1 end print(n .. "的阶乘是:" .. factorial)

内容详解:

  • while 关键字标志着 while 循环的开始。

  • 条件表达式 在每次循环迭代之前求值。如果为真,则执行循环体;如果为假,则循环结束。

  • do 关键字分隔条件表达式和循环体。

  • 循环体是需要重复执行的代码块。

  • end 关键字标志着 while 循环的结束。

  • 务必确保循环体中存在能够最终使条件表达式为假的操作,否则会导致无限循环。

2. for 循环:计数循环与迭代循环

Lua的 for 循环提供了两种形式:数值型 for 循环和泛型 for 循环,分别用于计数循环和迭代循环。

(1)数值型 for 循环:计数循环

数值型 for 循环用于按照指定的步长,从起始值迭代到结束值。

语法:

for 变量 = 起始值, 结束值, 步长 do -- 循环体代码 end
  • 步长可选,默认为 1。

  • 起始值、结束值和步长在循环开始时只计算一次。

  • 循环变量在循环体内部是局部变量,循环结束后失效。

代码实践 6:打印数字 1 到 10

for i = 1, 10 do print(i) end

代码实践 7:倒序打印数字 10 到 1

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

内容详解:

  • for 关键字标志着 for 循环的开始。

  • 变量 是循环变量,它会在每次循环迭代时被赋予新的值。

  • 起始值 是循环变量的初始值。

  • 结束值 是循环变量的终止值。当循环变量的值超过结束值时,循环结束。

  • 步长 是循环变量每次迭代的增量。如果省略,则默认为 1。

  • do 关键字分隔循环头和循环体。

  • end 关键字标志着 for 循环的结束。

(2)泛型 for 循环:迭代循环

泛型 for 循环通过迭代器函数遍历集合(如表、字符串等)中的元素。

语法:

for 变量1, 变量2, ... in 迭代器函数(集合) do -- 循环体代码 end
  • 迭代器函数负责提供每次迭代的值。

  • pairs() 迭代器用于遍历表的键值对。

  • ipairs() 迭代器用于遍历数组类型的表(索引从1开始的连续整数索引)。

  • string.gmatch() 迭代器用于遍历字符串中的模式匹配项。

代码实践 8:遍历表中的键值对

local myTable = {name = "Lua", version = 5.4, creator = "Roberto Ierusalimschy"} for key, value in pairs(myTable) do print(key .. ": " .. value) end

代码实践 9:遍历数组类型的表

local myArray = {"apple", "banana", "cherry"} for index, value in ipairs(myArray) do print(index .. ": " .. value) end

代码实践 10:遍历字符串中的单词

local text = "Lua is a powerful scripting language" for word in string.gmatch(text, "%w+") do -- %w+ 匹配一个或多个单词字符 print(word) end

内容详解:

  • 迭代器函数 返回一个迭代器函数、状态常量和初始控制变量。在每次循环迭代中,迭代器函数会被调用,返回集合中的下一个元素或多个元素。

  • pairs(table) 迭代器遍历表 table 中的所有键值对,键和值的顺序是不确定的。

  • ipairs(table) 迭代器遍历表 table 中的数组部分,即索引为 1, 2, 3, ... 的元素,顺序是确定的(索引顺序)。

  • string.gmatch(str, pattern) 迭代器遍历字符串 str 中所有匹配模式 pattern 的子串。

3. repeat-until 循环:后置条件循环

repeat-until 循环先执行循环体,然后在每次循环迭代之后检查条件表达式。只有当条件为真时循环才结束。这意味着 repeat-until 循环至少会执行一次循环体。

语法:

repeat -- 循环体代码 until 条件表达式

代码实践 11:简单的计数器

local count = 0 repeat count = count + 1 print("Count: " .. count) until count >= 5

内容详解:

  • repeat 关键字标志着 repeat-until 循环的开始。

  • 循环体是需要重复执行的代码块。

  • until 关键字标志着循环结束条件的开始。

  • 条件表达式 在每次循环迭代之后求值。如果为真,则循环结束;如果为假,则继续下一次循环迭代。

  • repeat-until 循环不需要 end 关键字来标记结束。

三、跳转语句:控制流程的灵活调整

跳转语句允许在循环或代码块中改变程序的执行流程,提供更灵活的控制能力。Lua主要提供了 breakgoto 语句。

1. break 语句:跳出循环

break 语句用于立即终止当前所在的循环(while, for, repeat-until),并将程序控制权转移到循环语句之后的下一条语句。

代码实践 12:在 for 循环中使用 break

for i = 1, 10 do if i == 5 then break -- 当 i 等于 5 时跳出循环 end print(i) end print("循环结束")

内容详解:

  • break 语句只能在循环体内部使用。

  • break 语句被执行时,程序会立即退出当前循环,不再执行循环体中剩余的代码以及后续的循环迭代。

2. goto 语句:无条件跳转 (慎用)

goto 语句允许程序无条件地跳转到程序中标记的标签位置。Lua 5.2 版本引入了 goto 语句,但应谨慎使用,过度使用 goto 可能会导致代码结构混乱,降低可读性和维护性。

语法:

goto 标签名 ::标签名::
  • 标签名以 :: 包围。

  • goto 语句跳转到同函数内定义的标签。

  • 标签的作用域是整个声明它的代码块。

代码实践 13:使用 goto 跳转

local x = 10 if x > 5 then goto label1 end print("这段代码不会执行") ::label1:: print("跳转到这里")

代码实践 14:使用 goto 模拟循环 (不推荐)

local i = 1 ::loop_start:: if i > 5 then goto loop_end end print(i) i = i + 1 goto loop_start ::loop_end:: print("循环结束")

内容详解:

  • goto 语句允许程序跳转到指定的标签位置执行代码。

  • 标签需要使用双冒号 :: 包围,并放置在代码的适当位置。

  • goto 语句跳转到标签时,会无条件地将程序控制权转移到标签所在的代码行。

  • 强烈建议避免过度使用 goto 语句。 在大多数情况下,可以使用结构化的控制语句(如 if, for, while)来代替 goto,使代码更易于理解和维护。goto 的使用场景通常局限于一些特定的情况,例如在深层嵌套的循环中快速跳出,或者实现状态机等复杂逻辑。

四、控制结构最佳实践

  • 保持代码简洁易懂: 选择最合适的控制结构来表达逻辑,避免过度复杂或嵌套过深的结构。

  • 使用有意义的变量名: 清晰的变量名可以增强代码的可读性,更容易理解控制结构的逻辑。

  • 适当的缩进和空格: 良好的代码格式可以清晰地展示控制结构的层次关系,提高代码可读性。

  • 避免无限循环: 在使用 whilerepeat-until 循环时,务必确保循环条件最终能够变为假,防止程序陷入无限循环。

  • 谨慎使用 goto 语句: 除非在特殊情况下,尽量使用结构化的控制语句来组织代码逻辑,减少 goto 的使用,提高代码的可维护性。

  • 充分利用逻辑运算符: 使用 and, or, not 等逻辑运算符可以简化复杂的条件表达式,提高代码效率和可读性。

总结

控制结构是Lua编程的基础和核心。掌握 if-then-else 条件语句、whileforrepeat-until 循环语句以及 breakgoto 跳转语句,是编写高效、可维护Lua代码的关键。通过本文的代码实践和内容详解,相信读者已经对Lua的控制结构有了深入的理解。在实际编程中,灵活运用这些控制结构,结合最佳实践,将能够构建出功能强大、逻辑清晰的Lua应用程序。


发布者: 作者: 转发
评论区 (0)
U