diff --git a/wiki/AI工程/Lua脚本语言研究.md b/wiki/AI工程/Lua脚本语言研究.md new file mode 100755 index 0000000..068782a --- /dev/null +++ b/wiki/AI工程/Lua脚本语言研究.md @@ -0,0 +1,343 @@ +--- +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 +#include +#include + +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 语言核心技术梳理*