6.7 KiB
Executable File
6.7 KiB
Executable File
created, type, tags
| created | type | tags | |||||
|---|---|---|---|---|---|---|---|
| 2026-05-03 | language |
|
Lua 脚本语言研究
轻量级、可嵌入的脚本语言,游戏和嵌入式领域的常青树 归档时间:2026-05-03
📌 简介
Lua(葡萄牙语"月亮")由巴西 PUC-Rio 大学于 1993 年开发,设计目标是嵌入到应用程序中,为其提供灵活的扩展能力。
- 官网:https://www.lua.org
- 当前版本:Lua 5.4(2020)
- 许可:MIT License
- 大小:核心解释器仅 ~300KB
⭐ 核心特性
| 特性 | 说明 |
|---|---|
| 轻量级 | 核心极小,内存占用低 |
| 可嵌入 | C/C++ API 完善,嵌入成本极低 |
| 高性能 | JIT 版本 LuaJIT 性能接近 C |
| 极简设计 | 只有 8 种数据类型,语法精简 |
| Table 万能 | 数组、字典、对象、模块全用 table |
| 协程支持 | 原生协程(coroutine),适合异步/游戏逻辑 |
🔤 基本语法速览
变量与类型
-- 8 种类型
local num = 42 -- number
local str = "hello" -- string
local bool = true -- boolean
local nil_val = nil -- nil
local tbl = {a=1, b=2} -- table
local func = print -- function
local thr = coroutine.create(function() end) -- thread
local usr = newproxy() -- userdata
-- 只有 nil 和 false 为假,0 和 "" 都是真!
Table(核心数据结构)
-- 数组
local arr = {10, 20, 30}
print(arr[1]) -- Lua 索引从 1 开始!
-- 字典
local dict = {name = "Lua", version = 5.4}
print(dict.name)
-- 混合
local mixed = {
x = 1, y = 2,
"first", "second"
}
-- 嵌套(模拟对象)
local obj = {
name = "Player",
hp = 100,
attack = function(self, target)
target.hp = target.hp - 10
end
}
控制流
-- if
if score >= 90 then
print("A")
elseif score >= 60 then
print("B")
else
print("C")
end
-- while / repeat
while i < 10 do
i = i + 1
end
repeat
line = io.read()
until line ~= ""
-- for
for i = 1, 10 do print(i) end -- 数值 for
for i = 10, 1, -1 do print(i) end -- 递减
for k, v in pairs(tbl) do print(k, v) end -- 泛型 for
函数
-- 基本定义
function add(a, b)
return a + b
end
-- 匿名函数 / 闭包
local make_counter = function()
local count = 0
return function()
count = count + 1
return count
end
end
-- 多返回值
function divmod(a, b)
return math.floor(a / b), a % b
end
local q, r = divmod(17, 5) -- q=3, r=2
-- 可变参数
function sum(...)
local total = 0
for _, v in ipairs({...}) do
total = total + v
end
return total
end
模块
-- mylib.lua
local M = {}
M.VERSION = "1.0"
function M.greet(name)
return "Hello, " .. name
end
return M
-- 使用
local mylib = require("mylib")
print(mylib.greet("World"))
🔌 嵌入 C/C++
最小嵌入示例
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
int main() {
lua_State *L = luaL_newstate();
luaL_openlibs(L);
// 执行 Lua 脚本
luaL_dostring(L, "print('Hello from Lua!')");
// 调用 Lua 函数
luaL_dostring(L, "function add(a,b) return a+b end");
lua_getglobal(L, "add");
lua_pushnumber(L, 3);
lua_pushnumber(L, 4);
lua_pcall(L, 2, 1, 0);
int result = lua_tonumber(L, -1);
printf("3 + 4 = %d\n", result);
lua_close(L);
return 0;
}
C 函数暴露给 Lua
static int l_cwrap(lua_State *L) {
double x = luaL_checknumber(L, 1);
lua_pushnumber(L, x * x);
return 1; // 返回值数量
}
// 注册
lua_pushcfunction(L, l_cwrap);
lua_setglobal(L, "cwrap");
// Lua 侧使用:print(cwrap(5)) → 25
🎮 主要应用场景
游戏脚本(最大应用领域)
| 游戏/引擎 | 用途 |
|---|---|
| World of Warcraft | UI 插件系统 |
| Roblox | 游戏逻辑(Luau 方言) |
| Unity | 通过 xLua/ToLua 热更新 |
| Cocos2d-x | 脚本层 |
| Garry's Mod | 模组脚本 |
| Redis | 服务器端脚本(EVAL) |
配置系统
-- config.lua
return {
server = {
host = "0.0.0.0",
port = 8080,
workers = 4
},
database = {
url = "mysql://localhost/mydb",
pool_size = 10
}
}
Nginx/OpenResty
-- access_by_lua_block
access_by_lua_block {
local redis = require "resty.redis"
local red = redis:new()
red:connect("127.0.0.1", 6379)
local ok, err = red:auth("password")
-- ... 限流/鉴权逻辑
}
Redis 脚本
-- 原子操作:检查 + 设置
local key = KEYS[1]
local val = redis.call('GET', key)
if val then
return tonumber(val) + 1
else
redis.call('SET', key, 1)
return 1
end
⚡ LuaJIT
LuaJIT 是 Lua 的 JIT 编译器,由 Mike Pall 开发:
- 性能:纯 Lua 代码可达 C 的 50%-80%
- FFI:直接调用 C 库,无需 C 包装层
- 广泛应用于:OpenResty、Torch、FFmpeg 滤镜等
-- LuaJIT FFI 示例
local ffi = require("ffi")
ffi.cdef[[
int printf(const char *fmt, ...);
]]
ffi.C.printf("Hello %s!\n", "World")
🆚 Lua vs Python/JavaScript
| 维度 | Lua | Python | JavaScript |
|---|---|---|---|
| 嵌入性 | ⭐⭐⭐⭐⭐ 专为嵌入设计 | ⭐⭐ 可嵌入但重 | ⭐⭐⭐ V8 可嵌入 |
| 体积 | ~300KB | ~30MB | ~5MB (V8) |
| 索引 | 从 1 开始 | 从 0 开始 | 从 0 开始 |
| 面向对象 | 基于 prototype | 基于 class | 基于 prototype |
| 生态 | 小而精 | 大而全 | 大而全 |
| 适合场景 | 嵌入/脚本/配置 | 通用/数据/AI | Web/全栈 |
💡 优缺点
优势
- ✅ 嵌入成本极低,C API 设计优雅
- ✅ 语法精简,学习曲线平缓
- ✅ 协程原生支持,游戏逻辑编写方便
- ✅ Table 一统天下,数据结构灵活
- ✅ LuaJIT 性能出色
劣势
- ❌ 标准库极小(没有正则、网络、文件系统)
- ❌ 索引从 1 开始,C 程序员易混淆
- ❌ 错误信息有时不够友好
- ❌ 缺乏包管理(luarocks 生态较小)
- ❌ 无内置调试器
🔧 工具链
| 工具 | 用途 |
|---|---|
| lua | 官方解释器 |
| luajit | JIT 编译器 |
| luarocks | 包管理器 |
| stylua | 代码格式化工具 |
| teal | Lua 类型系统 |
| selene | Lint 工具 |
| xLua/ToLua | Unity 热更新框架 |
📚 学习资源
- 官方手册:https://www.lua.org/manual/5.4/
- 《Programming in Lua》(PiL):官方教程
- Lua 5.3/5.4 中文版
- 实战:Redis EVAL、OpenResty、WoW 插件
研究归档,2026-05-03 | Lua 语言核心技术梳理