Lua 小白入门教程Lua 小白入门教程
首页
基础教程
实战进阶
编程指南
首页
基础教程
实战进阶
编程指南
  • 实战进阶

    • 🚀 实战进阶
    • 第1章 - 模块与包管理
    • 第2章 - 文件 I/O 操作
    • 第3章 - 错误处理
    • 第4章 - 面向对象编程
    • 第5章 - SpringBoot + Lua 整合实战 ⭐
    • 第6章 - Redis + Lua 脚本 ⭐
    • 第7章 - OpenResty 入门
    • 第8章 - 最佳实践与常见坑

第1章 - 模块与包管理

嗨,朋友!我是长安。

写过 Java 的你一定对 package 和 import 非常熟悉。Lua 也有自己的模块系统,虽然没有 Java 那么严格,但足够灵活。

🤔 什么是模块?

在 Java 中,你用 package 和 class 来组织代码。在 Lua 中,一个文件就是一个模块,通过 require 来加载。

概念JavaLua
模块定义package + class一个 .lua 文件
导入import xxx.yyyrequire("xxx")
导出public 关键字return 一个 Table
包管理Maven / GradleLuaRocks

📦 创建模块

创建一个工具模块

-- utils.lua
local M = {}    -- 模块表

function M.add(a, b)
    return a + b
end

function M.sub(a, b)
    return a - b
end

function M.formatName(firstName, lastName)
    return lastName .. firstName
end

-- 私有函数(不放到 M 表中,外部无法访问)
local function validate(value)
    return value ~= nil
end

function M.safePrint(value)
    if validate(value) then
        print(value)
    else
        print("nil value")
    end
end

return M    -- 返回模块表

使用模块

-- main.lua
local utils = require("utils")

print(utils.add(3, 5))              -- 8
print(utils.sub(10, 3))             -- 7
print(utils.formatName("安", "长"))  -- 长安
utils.safePrint("Hello")            -- Hello
utils.safePrint(nil)                -- nil value

Java 对比

// Utils.java
public class Utils {
    public static int add(int a, int b) {
        return a + b;
    }
    
    public static int sub(int a, int b) {
        return a - b;
    }
    
    private static boolean validate(Object value) {
        return value != null;
    }
}

// Main.java
import com.example.Utils;

public class Main {
    public static void main(String[] args) {
        System.out.println(Utils.add(3, 5));  // 8
    }
}

🔒 模块的私有与公开

-- mymodule.lua
local M = {}

-- 公开的(放入 M 表)
function M.publicMethod()
    print("我是公开方法")
end

-- 私有的(local 函数,不放入 M 表)
local function privateMethod()
    print("我是私有方法")
end

-- 公开方法可以调用私有方法
function M.doSomething()
    privateMethod()    -- 内部可以调用
    print("做了一些事情")
end

return M

类比 Java

  • 放入 M 表中的函数 → public 方法
  • local 函数不放入 M 表 → private 方法
  • 模块表 M → Java 类

📂 模块路径

require 会在一系列路径中查找模块:

-- 查看模块搜索路径
print(package.path)
-- 通常输出类似:
-- ./?.lua;/usr/local/share/lua/5.4/?.lua;...

-- ? 会被替换为模块名
-- require("utils") 会依次查找:
-- ./utils.lua
-- /usr/local/share/lua/5.4/utils.lua
-- ...

子目录模块

-- 文件结构:
-- project/
-- ├── main.lua
-- └── lib/
--     └── json.lua

-- 加载子目录模块
local json = require("lib.json")    -- 用 . 分隔目录

注意

Lua 用 . 作为路径分隔符(不是 /),这和 Java 的 import com.example.Utils 类似。

🔄 require 的缓存机制

require 加载模块后会缓存结果,多次 require 同一个模块只会执行一次:

-- 第一次加载:执行模块代码
local m1 = require("mymodule")

-- 第二次加载:直接返回缓存,不会重新执行
local m2 = require("mymodule")

print(m1 == m2)    -- true(是同一个对象)

-- 如果需要强制重新加载:
package.loaded["mymodule"] = nil    -- 清除缓存
local m3 = require("mymodule")     -- 重新执行

Java 对比

这和 Java 的类加载器缓存机制类似——一个类只会被加载一次(除非用不同的 ClassLoader)。

📦 LuaRocks — Lua 的包管理器

LuaRocks 之于 Lua,就像 Maven 之于 Java:

# 安装 LuaRocks
# macOS
brew install luarocks

# 安装一个包
luarocks install luasocket
luarocks install lua-cjson

# 查看已安装的包
luarocks list

# 搜索包
luarocks search json
操作Maven (Java)LuaRocks (Lua)
安装依赖mvn installluarocks install xxx
搜索包mvnrepository.comluarocks search xxx
配置文件pom.xml.rockspec
仓库Maven Centralluarocks.org

📝 小结

  • 一个 Lua 文件就是一个模块,通过 return 导出
  • 用 require("模块名") 导入模块
  • local 函数 = 私有,放入模块表 = 公开
  • require 有缓存机制,多次调用不会重复执行
  • LuaRocks 是 Lua 的包管理器,类似 Maven

➡️ 下一步

模块化搞定了!下一章来学习 文件 I/O 操作。

💪 练习题

  1. 创建一个 math_utils.lua 模块,包含 square(x) 和 cube(x) 两个公开函数。
  2. 在另一个文件中 require 并调用这两个函数。
  3. 如何在模块中实现"私有"函数?
  4. require 的缓存机制是什么?如何强制重新加载?

答案提示

  1. local M = {} function M.square(x) return x*x end function M.cube(x) return x*x*x end return M
  2. local mu = require("math_utils") print(mu.square(5))
  3. 用 local function 定义,不放入模块表 M 中
  4. 首次加载后缓存结果,package.loaded["xxx"] = nil 清除缓存
最近更新: 2026/2/27 17:54
Contributors: 王长安
Prev
🚀 实战进阶
Next
第2章 - 文件 I/O 操作