Files
chill_notes/wiki/AI工程/Lua脚本语言研究.md
2026-05-03 23:53:10 +08:00

344 lines
6.7 KiB
Markdown
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
created: 2026-05-03
type: language
tags: [Lua, 脚本语言, 嵌入式, 游戏开发, 配置文件]
---
# Lua 脚本语言研究
> 轻量级、可嵌入的脚本语言,游戏和嵌入式领域的常青树
> 归档时间2026-05-03
---
## 📌 简介
**Lua**(葡萄牙语"月亮")由巴西 PUC-Rio 大学于 1993 年开发,设计目标是**嵌入到应用程序中**,为其提供灵活的扩展能力。
- 官网https://www.lua.org
- 当前版本Lua 5.42020
- 许可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 语言核心技术梳理*