Lua语法进阶:函数封装与条件控制的艺术

在上一篇文章中,我们掌握了 Lua 的变量声明和循环结构。今天,我们将继续深入,探索 Lua 的函数定义条件控制

对于习惯了 Java 的开发者来说,Lua 的语法风格可能会让你感到既熟悉又陌生。它没有大括号 {},而是用 thenend 来划分代码块;它没有 &&||,而是直接使用英文单词。这种设计虽然初看有些"另类",但实际上让代码读起来更像自然语言,简洁而优雅。

一、函数:代码复用的基石

在编程中,封装是核心思想之一。Lua 的函数定义非常直观,但有几个关键点需要特别注意。

1. 基本语法结构

Lua 使用 function 关键字来声明函数。与 JavaScript 或 Java 不同,Lua 不需要大括号来包裹函数体,而是以 end 结尾。

复制代码
-- 定义一个函数
function printArr(arr)
    for index, value in ipairs(arr) do
        print(value)
    end
end

2. 局部函数

为了遵循最佳实践,我们通常建议使用 local 关键字来声明函数,将其限制在局部作用域内,避免污染全局环境。

复制代码
local function printArr(arr)
    -- 函数体
end

3. 调用方式

调用函数非常简单,直接写函数名加参数即可:

复制代码
printArr({'java', 'lua'})
二、条件控制:告别大括号

Lua 的流程控制语句在设计上非常注重可读性。如果你习惯了 Java 的 if (condition) { ... },那么 Lua 的写法可能需要你转换一下思维。

1. if...then...end 结构

Lua 使用 then 来开启代码块,使用 end 来结束代码块。

复制代码
if (a > 10) then
    print("大于10")
else
    print("小于等于10")
end

2. 逻辑运算符:英文单词流

这是 Java 开发者最容易"翻车"的地方。Lua 不支持 &&||! 这样的符号,而是强制使用英文单词:

  • and :对应 Java 的 &&。若 A 为 false,则返回 A,否则返回 B。
  • or :对应 Java 的 ||。若 A 为 true,则返回 A,否则返回 B。
  • not :对应 Java 的 !。对结果取反。

3. 真假值的陷阱

在 Java 中,只有 false 是假。但在 Lua 中,falsenil 都是假 ,而其他所有值(包括 0 和空字符串 "")都被视为真。

这意味着:

  • not nil 的结果是 true
  • if (0) then ... end 会执行 then 后面的代码,因为 0 在 Lua 中被视为真。
三、实战案例:打造健壮性函数

理论讲完了,我们来写一个实用的函数。假设我们需要封装一个打印数组的函数,但为了系统的健壮性,我们需要在传入参数为 nil 时进行拦截,避免程序崩溃。

需求:

增强 printArr 函数,当参数为 nil 时打印错误信息,并终止执行。

代码实现:

复制代码
local function printArr(arr)
    -- 防御式编程:优先校验非法输入
    if not arr then
        print("数组不能为空")
        return -- 提前返回,避免后续代码执行
    end

    -- 正常逻辑
    for i, val in ipairs(arr) do
        print(val)
    end
end

测试效果:

  • 传入正常数组 {'java', 'lua'}:正确遍历打印。
  • 传入 nil:输出 "数组不能为空",程序安全退出。

这种"防御式编程"的思想在 Lua 开发中非常重要,特别是在处理 Nginx 请求参数时,我们永远不能假设输入一定是合法的。

总结与展望

Lua 的函数和条件控制虽然语法简单,但 local 的作用域管理、英文逻辑运算符以及 nil 的特殊性都是开发中必须牢记的细节。

掌握了这些,你就具备了编写完整业务逻辑的能力。接下来,我们将把这些知识结合起来,在 Nginx 中编写真正的 Lua 脚本,处理 HTTP 请求!


知识点核心总结
知识点 核心内容 考试重点/易混淆点 难度系数
Lua函数声明 function关键字声明,无大括号,end结尾,支持return返回值 与JS语法对比:相似但无大括号
函数封装案例 print_arr函数封装数组遍历逻辑(for k,v in pairs(arr)循环结构) 复用价值:消除重复for循环代码 参数要求:需传入数组类型变量
条件控制语法 if...then...end结构,布尔运算使用and/or/not单词而非符号 关键差异: - nil等价false - not nil返回true 易错点:逻辑运算符与Java差异
健壮性处理 通过if not arr then print("数组不能为空") return end实现空值校验 防御式编程: - 优先校验非法输入 - 提前return终止流程
布尔表达式 比较运算符与Java相同,但逻辑运算符需用英文单词: - and替代&& - or替代 !
相关推荐
我不想名字重复2 小时前
redis缓存和数据库数据保持一致
数据库·redis·缓存
时空无限2 小时前
vllm 大模型启动缓存相关环境变量 export
linux·缓存·vllm
风中凌乱4 小时前
kafka新版本集群的安装与部署
分布式·kafka
流星白龙4 小时前
【Redis】8.List列表
redis
NWU_白杨4 小时前
三种常用的数据存储技术
数据库·redis·mysql·sqlite
SLD_Allen4 小时前
大规模分布式AI训练基础设施
人工智能·分布式·模型训练
我叫黑大帅5 小时前
我为什么单一消费者的场景下,要用 Redis List 当消息队列?
redis·后端·面试
正儿八经的少年5 小时前
redis 的大 key 和热 key 详解
数据库·redis·缓存
富士康质检员张全蛋6 小时前
Kafka的操作-消费的详情
分布式·kafka
X-⃢_⃢-X6 小时前
十、Redis之布隆过滤器
数据库·redis·缓存