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替代 !
相关推荐
ltl3 小时前
2PC 的真实失败模式:阻塞、脑裂与恢复
分布式
霸道流氓气质5 小时前
分布式系统设计:技术解析与实践
分布式
ACP广源盛139246256738 小时前
蚂蚁百灵 Ling‑3.0‑flash 开源 + 昇腾 0‑Day 原生适配@ACP#GSV9001E 在国产算力矩阵中的机会与落地场景
大数据·人工智能·分布式·单片机·嵌入式硬件
小努蛋9 小时前
linux编译openresty异常问题,lua_cjson.c:706:5: 错误: ‘for‘ 循环初始化声明只在 C99 或 C++ 模式下允许
开发语言·lua·openresty
天疆说9 小时前
01 硬件选型与 llama.cpp 部署:4× RTX 5880 Ada 跑 DeepSeek-V4-Flash
java·redis·llama
嘟嘟071710 小时前
Next.js 博客左侧笔记列表是怎么从 Redis 渲染出来的?从组件、children 到动态路由一次讲清
redis·react.js·前端工程化
番茄炒鸡蛋加糖11 小时前
项目技术点总结--四大核心技术+缓存
缓存
大飞记Python11 小时前
AI大模型Token计费全解析:输入/输出、缓存命中、阶梯计价一文看懂
人工智能·缓存
汽车仪器仪表相关领域12 小时前
KRYPTON坚固型IP67 EtherCAT总线数据采集模块:工业级分布式采集方案
分布式·功能测试·汽车·压力测试·可用性测试
Rain的Java大神之路12 小时前
线上接口负载满了如何解决
java·数据库·redis·后端·缓存·面试·架构