344 lines
6.7 KiB
Markdown
Executable File
344 lines
6.7 KiB
Markdown
Executable File
---
|
||
created: 2026-05-03
|
||
type: language
|
||
tags: [Lua, 脚本语言, 嵌入式, 游戏开发, 配置文件]
|
||
---
|
||
|
||
# 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),适合异步/游戏逻辑 |
|
||
|
||
---
|
||
|
||
## 🔤 基本语法速览
|
||
|
||
### 变量与类型
|
||
|
||
```lua
|
||
-- 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(核心数据结构)
|
||
|
||
```lua
|
||
-- 数组
|
||
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
|
||
}
|
||
```
|
||
|
||
### 控制流
|
||
|
||
```lua
|
||
-- 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
|
||
```
|
||
|
||
### 函数
|
||
|
||
```lua
|
||
-- 基本定义
|
||
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
|
||
```
|
||
|
||
### 模块
|
||
|
||
```lua
|
||
-- 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++
|
||
|
||
### 最小嵌入示例
|
||
|
||
```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
|
||
|
||
```c
|
||
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) |
|
||
|
||
### 配置系统
|
||
|
||
```lua
|
||
-- config.lua
|
||
return {
|
||
server = {
|
||
host = "0.0.0.0",
|
||
port = 8080,
|
||
workers = 4
|
||
},
|
||
database = {
|
||
url = "mysql://localhost/mydb",
|
||
pool_size = 10
|
||
}
|
||
}
|
||
```
|
||
|
||
### Nginx/OpenResty
|
||
|
||
```lua
|
||
-- 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 脚本
|
||
|
||
```lua
|
||
-- 原子操作:检查 + 设置
|
||
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 滤镜等
|
||
|
||
```lua
|
||
-- 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 语言核心技术梳理*
|