Lua 5.4 语法与核心知识学习总结
**学习时间**: 2026 年 3 月 14 日 **文档来源**: https://lua.org/docs.html **参考版本**: Lua 5.4 **参考书籍**: 《Programming in Lua》(第一版) - Roberto Ierusalimschy---## 一、Lua 概述### 1.1 什么是 LuaLua 是一种**轻量、可嵌入、多范式**的脚本语言具有以下特点| 特性 | 说明 ||------|------|| **轻量级** | 核心库非常小易于嵌入到应用程序中 || **可嵌入** | 提供完整的 C API方便与 C/C 集成 || **多范式** | 支持过程式、函数式、面向对象编程 || **动态类型** | 运行时类型检查灵活但需注意类型安全 || **即时编译** | 通过 LuaJIT 可获得 JIT 编译支持 || **协程支持** | 内置协程支持协作式多任务 |### 1.2 设计目标- **简洁**: 语言核心小巧易于学习和实现- **高效**: 针对性能优化适合嵌入式和游戏开发- **可扩展**: 通过 C API 轻松扩展功能- **可移植**: 纯 C 实现可在几乎所有平台上运行---## 二、数据类型Lua 有 **8 种基本数据类型**### 2.1 nil (空值)lualocal a nilprint(a nil) -- trueprint(type(a)) -- nil- nil 类型只有一个值nil- 全局变量默认值为 nil- 将变量设为 nil 可删除该变量---### 2.2 boolean (布尔值)lualocal a truelocal b false-- 假值nil 和 false-- 真值所有其他值包括 0 和空字符串if 0 then print(0 is true) end -- 会执行if then print(empty string is true) end -- 会执行---### 2.3 number (数字)lualocal a 10 -- 整数local b 3.14 -- 浮点数local c 0x1F -- 十六进制local d 3.0e8 -- 科学计数法-- Lua 5.3 支持整数和浮点数两种内部表示print(type(10)) -- numberprint(math.type(10)) -- integerprint(math.type(3.14)) -- float---### 2.4 string (字符串)lualocal s1 Hellolocal s2 Worldlocal s3 [[多行字符串]]local s4 \u{41} -- Unicode (Lua 5.3)-- 字符串是不可变的-- 字符串索引从 1 开始print(string.sub(Hello, 1, 3)) -- Helprint(Hello[1]) -- 错误需要用 string.sub---### 2.5 function (函数)lua-- 普通函数function add(a, b)return a bend-- 匿名函数local multiply function(a, b)return a * bend-- 作为参数传递table.sort({3,1,2}, function(a,b) return ab end)---### 2.6 userdata (用户数据)lua-- 用于存储 C 数据结构-- 由 C API 创建和管理local file io.open(test.txt) -- file 是 userdata- 用于在 Lua 中存储 C 数据- 没有预定义操作需通过元表定义行为---### 2.7 thread (线程/协程)lualocal co coroutine.create(function()print(协程运行)coroutine.yield(1)print(协程继续)end)print(type(co)) -- thread- 用于实现协程- 不是操作系统线程是协作式多任务---### 2.8 table (表)lua-- Lua 中最重要的数据结构local t1 {} -- 空表local t2 {1, 2, 3} -- 数组local t3 {key value} -- 字典/对象local t4 {name Lua,version 5.4,{1, 2, 3} -- 嵌套表}-- 表是引用类型local a {1, 2}local b a -- b 引用同一个表**表的特点**- 既是数组又是字典关联数组- 索引默认从 1 开始- 键可以是任何非 nil 值- 是 Lua 中唯一的复合数据结构---## 三、变量与作用域### 3.1 变量类型lua-- 全局变量默认globalVar 10-- 局部变量local localVar 20-- 多变量赋值local x, y, z 1, 2, 3-- 交换值x, y y, x### 3.2 作用域规则lua-- 全局作用域globalVar 10function test()-- 函数内未声明 local 的变量是全局的globalVar 20 -- 修改全局变量-- 局部变量local localVar 30 -- 只在函数内有效-- 代码块作用域dolocal blockVar 40 -- 只在代码块内有效print(blockVar) -- 40end-- print(blockVar) -- 错误超出作用域end### 3.3 _G 全局环境表lua-- 访问全局变量print(_G[globalVar]) -- 10-- 动态创建全局变量_G[dynamicVar] 100print(dynamicVar) -- 100---## 四、表达式与运算符### 4.1 算术运算符lualocal a, b 10, 3print(a b) -- 13 加法print(a - b) -- 7 减法print(a * b) -- 30 乘法print(a / b) -- 3.333... 除法print(a % b) -- 1 取模print(a ^ b) -- 1000 幂运算print(-a) -- -10 负号print(a // b) -- 3 整除 (Lua 5.3)---### 4.2 关系运算符lualocal a, b 10, 3print(a b) -- false 等于print(a ~ b) -- true 不等于print(a b) -- true 大于print(a b) -- false 小于print(a b) -- true 大于等于print(a b) -- false 小于等于-- 注意 比较表时比较的是引用local t1 {}local t2 {}print(t1 t2) -- false (不同引用)local t3 t1print(t1 t3) -- true (相同引用)---### 4.3 逻辑运算符lua-- and: 如果第一个操作数为假返回第一个操作数否则返回第二个print(false and A or B) -- Bprint(true and A or B) -- A-- or: 如果第一个操作数为真返回第一个操作数否则返回第二个print(nil or default) -- defaultprint(false or 0) -- 0-- not: 逻辑非print(not nil) -- trueprint(not false) -- trueprint(not 0) -- false (0 是真值)-- 三元运算符技巧local x condition and trueValue or falseValue---### 4.4 连接运算符lualocal s1 Hellolocal s2 Worldlocal s3 s1 .. .. s2 -- Hello World-- 数字需要转换local n 10print(Value: .. tostring(n)) -- Value: 10---### 4.5 长度运算符lualocal s Helloprint(#s) -- 5local t {1, 2, 3}print(#t) -- 3-- 注意# 对哈希表非连续键行为未定义---### 4.6 优先级从高到低^not # - * / // % -.. ~ andor---## 五、控制结构### 5.1 if then elselualocal age 18if age 13 thenprint(儿童)elseif age 20 thenprint(青少年)elseif age 60 thenprint(成年人)elseprint(老年人)end-- 单行 ifif condition then doSomething() end---### 5.2 while 循环lualocal i 1while i 5 doprint(i)i i 1end---### 5.3 repeat untillua-- 至少执行一次local i 1repeatprint(i)i i 1until i 5---### 5.4 数值 for 循环lua-- 递增for i 1, 5 doprint(i)end-- 指定步长for i 10, 1, -2 doprint(i) -- 10, 8, 6, 4, 2end-- 嵌套循环for i 1, 3 dofor j 1, 3 doprint(i, j)endend---### 5.5 通用 for 循环lua-- 遍历数组local t {1, 2, 3, 4, 5}for i, v in ipairs(t) doprint(i, v)end-- 遍历字典local d {name Lua, version 5.4}for k, v in pairs(d) doprint(k, v)end-- 遍历字符串for c in string.gmatch(Hello, .) doprint(c)end---### 5.6 break 和 returnlua-- break 跳出循环for i 1, 10 doif i 5 thenbreakendprint(i)end-- return 返回值并结束函数function divide(a, b)if b 0 thenreturn nil, 除数不能为零endreturn a / bendlocal result, err divide(10, 0)if err then print(err) end---## 六、函数深入### 6.1 多返回值luafunction getMinMax(t)local min, max t[1], t[1]for i 2, #t doif t[i] min then min t[i] endif t[i] max then max t[i] endendreturn min, maxendlocal t {3, 1, 4, 1, 5, 9}local min, max getMinMax(t)print(min, max) -- 1, 9-- 捕获多个返回值local a, b, c getMinMax(t) -- c 为 nil函数只返回两个值---### 6.2 可变参数lua-- 可变参数函数function sum(...)local total 0local args {...} -- 将参数收集到表中for i, v in ipairs(args) dototal total vendreturn totalendprint(sum(1, 2, 3, 4, 5)) -- 15-- 固定参数 可变参数function printf(format, ...)print(string.format(format, ...))endprintf(Hello, %s! You are %d years old., Alice, 25)---### 6.3 命名参数模拟lua-- Lua 不直接支持命名参数但可以用表模拟function createWindow(options)local title options.title or Untitledlocal width options.width or 800local height options.height or 600local x options.x or 0local y options.y or 0print(title, width, height, x, y)end-- 调用createWindow{title My Window,width 1024,height 768}---## 七、闭包与上值### 7.1 闭包概念**闭包**是函数与其引用环境的组合。闭包可以访问其定义时所在作用域的变量即使该作用域已经结束。luafunction createCounter()local count 0 -- 局部变量return function() -- 闭包count count 1return countendendlocal counter1 createCounter()local counter2 createCounter()print(counter1()) -- 1print(counter1()) -- 2print(counter2()) -- 1 (独立的计数器)---### 7.2 上值 (Upvalues)**上值**是闭包捕获的外部局部变量。luafunction makeAdder(n)return function(x)return x n -- n 是上值endendlocal add5 makeAdder(5)local add10 makeAdder(10)print(add5(3)) -- 8print(add10(3)) -- 13---### 7.3 共享上值lua-- 多个闭包共享同一个上值function makeAccount(initialBalance)local balance initialBalancefunction deposit(amount)balance balance amountendfunction withdraw(amount)if amount balance thenbalance balance - amountreturn trueendreturn falseendfunction getBalance()return balanceendreturn {deposit deposit,withdraw withdraw,getBalance getBalance}endlocal account makeAccount(100)account.deposit(50)account.withdraw(30)print(account.getBalance()) -- 120---### 7.4 迭代器闭包lua-- 创建自定义迭代器function listIterator(list)local i 0local n #listreturn function()i i 1if i n thenreturn list[i]endendendlocal list {1, 2, 3, 4, 5}for element in listIterator(list) doprint(element)end---## 八、协程### 8.1 协程基础协程是**协作式多任务**一次只有一个协程在运行只有显式请求时才会暂停。lua-- 创建协程local co coroutine.create(function(a, b)print(协程开始, a, b)local c coroutine.yield(a b)print(协程继续, c)return a * bend)-- 恢复协程print(coroutine.resume(co, 2, 3)) -- true, 5print(coroutine.resume(co, 10)) -- true, 6print(coroutine.resume(co)) -- false, cannot resume dead coroutine---### 8.2 协程状态lualocal co coroutine.create(function() end)print(coroutine.status(co)) -- suspendedcoroutine.resume(co)print(coroutine.status(co)) -- dead-- 状态类型:-- suspended: 已让出或尚未开始-- running: 正在执行-- normal: 已启动但当前未执行-- dead: 已执行完毕或出错---### 8.3 协程作为生成器lua-- 生成 1 到 5 的循环生成器function numberGenerator()local co coroutine.create(function()while true dofor i 1, 5 docoroutine.yield(i)endendend)return function()local _, value coroutine.resume(co)return valueendendlocal nextNumber numberGenerator()for i 1, 10 doprint(nextNumber())end-- 输出: 1,2,3,4,5,1,2,3,4,5---### 8.4 协程包装器lua-- coroutine.wrap 返回一个函数调用即恢复协程local co coroutine.wrap(function()for i 1, 5 docoroutine.yield(i)endend)for i 1, 5 doprint(co())end---## 九、元表与元方法### 9.1 元表概念**元表**是改变表行为的表通过**元方法**定义。lualocal t {1, 2, 3}local mt {__index function(table, key)return 默认值 .. keyend}setmetatable(t, mt)print(t[1]) -- 1 (存在)print(t[4]) -- 默认值4 (不存在触发 __index)---### 9.2 完整元方法列表| 元方法 | 运算符/操作 | 说明 ||--------|------------|------|| __index | table[key] | 键不存在时的查找 || __newindex | table[key] value | 键不存在时的赋值 || __add | | 加法 || __sub | - | 减法 || __mul | * | 乘法 || __div | / | 除法 || __mod | % | 取模 || __unm | - | 负号 || __idiv | // | 整除 || __pow | ^ | 幂运算 || __concat | .. | 连接 || __eq | | 等于 || __lt | | 小于 || __le | | 小于等于 || __call | () | 调用 || __tostring | tostring() | 字符串表示 || __len | # | 长度 || __pairs | pairs() | pairs 迭代 || __gc | - | 垃圾回收回调 |---### 9.3 __index 元方法lua-- 方式一使用函数local t {key1 value1}local mt {__index function(table, key)if key key2 thenreturn metatablevalueendreturn nilend}setmetatable(t, mt)print(t.key1, t.key2) -- value1, metatablevalue-- 方式二使用表简化local t {key1 value1}setmetatable(t, {__index {key2 metatablevalue}})print(t.key1, t.key2) -- value1, metatablevalue---### 9.4 __newindex 元方法lua-- 将新键值存储到元表中local mymetatable {}local mytable setmetatable({key1 value1}, {__newindex mymetatable})mytable.newkey new valueprint(mytable.newkey, mymetatable.newkey) -- nil, new value-- 使用 rawset 直接设置local t setmetatable({}, {__newindex function(table, key, value)rawset(table, key, \..value..\)end})t.key valueprint(t.key) -- value---### 9.5 运算符重载lua-- 向量加法local Vector {}Vector.__index Vectorfunction Vector.new(x, y)return setmetatable({x x, y y}, Vector)endfunction Vector.__add(a, b)return Vector.new(a.x b.x, a.y b.y)endfunction Vector.__tostring(v)return ( .. v.x .. , .. v.y .. )endlocal v1 Vector.new(1, 2)local v2 Vector.new(3, 4)local v3 v1 v2print(v3) -- (4, 6)---### 9.6 可调用表lualocal t setmetatable({10, 20, 30}, {__call function(table, newtable)local sum 0for i, v in ipairs(table) dosum sum vendfor i, v in ipairs(newtable) dosum sum vendreturn sumend})print(t({10, 20, 30})) -- 120---### 9.7 自定义字符串表示lualocal t setmetatable({10, 20, 30}, {__tostring function(table)local sum 0for k, v in pairs(table) dosum sum vendreturn The sum is .. sumend})print(t) -- The sum is 60---## 十、标准库### 10.1 字符串库 (string)lua-- 基本操作string.len(Hello) -- 5string.lower(HELLO) -- hellostring.upper(hello) -- HELLOstring.rep(ab, 3) -- abababstring.reverse(abc) -- cbastring.sub(Hello, 2, 4) -- ell-- 查找与匹配string.find(Hello Lua, Lua) -- 7, 9string.match(I have 2 questions, %d %a) -- 2 questions-- 替换string.gsub(banana, a, A, 2) -- bAnAna, 2-- 迭代for word in string.gmatch(Hello Lua user, %a) doprint(word)end-- 格式化string.format(%s %q, Hello, Lua) -- Hello Luastring.format(%d, %.2f, 10, 3.14159) -- 10, 3.14---### 10.2 模式匹配| 模式 | 含义 ||------|------|| . | 任意字符 || %a | 字母 || %d | 数字 || %s | 空白字符 || %w | 字母和数字 || %A, %D, %S, %W | 取反 || | 1 次或多次 || * | 0 次或多次 || - | 0 次或多次非贪婪 || ? | 0 次或 1 次 || ^ | 字符串开头 || $ | 字符串结尾 || %b() | 平衡括号 |lua-- 示例string.match(hello123, %a) -- hellostring.match(hello123, %d) -- 123string.gsub(a(b(c)d)e, %b(), ) -- ae---### 10.3 表库 (table)lua-- 插入table.insert(t, value) -- 末尾插入table.insert(t, pos, value) -- 指定位置插入-- 移除table.remove(t) -- 移除末尾table.remove(t, pos) -- 移除指定位置-- 连接table.concat({1,2,3}, -) -- 1-2-3-- 排序table.sort({3,1,2}) -- {1,2,3}table.sort({3,1,2}, function(a,b) return ab end) -- 降序-- 移动 (Lua 5.3)table.move(src, first, last, offset, dest)---### 10.4 数学库 (math)luamath.pi -- 3.14159...math.huge -- 无穷大math.abs(-10) -- 10math.ceil(3.14) -- 4math.floor(3.14) -- 3math.max(1,2,3) -- 3math.min(1,2,3) -- 1math.pow(2, 10) -- 1024math.sqrt(16) -- 4math.random() -- [0,1) 随机数math.random(1, 100) -- [1,100] 随机整数math.type(10) -- integer 或 float---### 10.5 I/O 库 (io)lua-- 简单 I/Oio.write(Hello)local line io.read(l) -- 读取一行local content io.read(*a) -- 读取全部-- 文件操作local file io.open(test.txt, r)if file thenlocal content file:read(*a)file:close()end-- 写入文件local file io.open(output.txt, w)file:write(Hello, World!\n)file:close()-- 自动关闭for line in io.lines(test.txt) doprint(line)end---### 10.6 操作系统库 (os)luaos.time() -- 当前时间戳os.time{year2024, month1, day1} -- 指定时间os.date() -- 当前日期字符串os.date(%Y-%m-%d) -- 2024-01-14os.date(*t) -- 时间表格os.clock() -- CPU 时间os.getenv(PATH) -- 环境变量os.execute(ls -l) -- 执行命令os.remove(file.txt) -- 删除文件os.rename(old, new) -- 重命名---### 10.7 调试库 (debug)lua-- 内省debug.getinfo(func) -- 获取函数信息debug.getlocal(func, i) -- 获取局部变量debug.getupvalue(func, i) -- 获取上值-- 钩子debug.sethook(func, mask, count)-- 其他debug.traceback() -- 回溯信息debug.getmetatable(t) -- 获取元表debug.setmetatable(t, mt) -- 设置元表---### 10.8 模块系统lua-- 创建模块 (mymodule.lua)local M {}function M.hello()print(Hello from module)endM.VERSION 1.0return M-- 使用模块local mymodule require(mymodule)mymodule.hello()print(mymodule.VERSION)-- package.path 和 package.cpathprint(package.path) -- Lua 模块搜索路径print(package.cpath) -- C 模块搜索路径---## 十一、面向对象编程### 11.1 类与对象lua-- 定义类local Animal {}Animal.__index Animalfunction Animal:new(name, age)local obj setmetatable({}, self)obj.name nameobj.age agereturn objendfunction Animal:speak()print(self.name .. makes a sound)end-- 创建对象local dog Animal:new(Dog, 3)dog:speak() -- Dog makes a sound---### 11.2 继承lualocal Dog setmetatable({}, {__index Animal})Dog.__index Dogfunction Dog:new(name, age, breed)local obj Animal.new(self, name, age)obj.breed breedreturn objendfunction Dog:speak()print(self.name .. barks)endlocal myDog Dog:new(Buddy, 2, Golden)myDog:speak() -- Buddy barks---### 11.3 多重继承luafunction searchInTable(table, key)local value table[key]if value ~ nil then return value endendfunction createClass(...)local c {}local parents {...}setmetatable(c, {__index function(t, k)for i, parent in ipairs(parents) dolocal v searchInTable(parent, k)if v then return v endendend})c.__index creturn cend---### 11.4 隐私保护lua-- 使用闭包实现私有成员function createAccount(initialBalance)local balance initialBalance -- 私有变量return {deposit function(amount)balance balance amountend,withdraw function(amount)if amount balance thenbalance balance - amountreturn trueendreturn falseend,getBalance function()return balanceend}endlocal account createAccount(100)-- account.balance 无法直接访问---## 十二、最佳实践### 12.1 性能优化lua-- 1. 使用局部变量local print print -- 缓存全局函数for i 1, 1000 doprint(i) -- 比访问 _G.print 快end-- 2. 字符串连接使用 table.concatlocal t {}for i 1, 1000 dot[i] item .. iendlocal s table.concat(t, ,) -- 比 .. 高效-- 3. 预分配表大小local t {}for i 1, 1000 dot[i] i -- Lua 会自动优化end-- 4. 避免不必要的表创建function sum(a, b, c)return a b c -- 不要返回表end---### 12.2 错误处理lua-- 使用 pcalllocal status, result pcall(function()error(Something went wrong)end)if not status thenprint(Error:, result)end-- 使用 xpcall带回溯local status, result xpcall(function()error(Error)end, debug.traceback)-- 自定义错误处理function myHandler(err)print(Error:, err)return handledendxpcall(function()error(test)end, myHandler)---### 12.3 内存管理lua-- 1. 及时释放不需要的引用local largeTable {}-- ... 使用 ...largeTable nil -- 允许 GC 回收-- 2. 使用弱表local cache setmetatable({}, {__mode v}) -- 弱值local weakKeys setmetatable({}, {__mode k}) -- 弱键-- 3. 避免循环引用-- 循环引用会阻止 GC 回收---### 12.4 代码组织lua-- 1. 使用模块组织代码-- mymodule.lualocal M {}-- 私有函数local function privateFunc()-- ...end-- 公共 APIfunction M.publicFunc()privateFunc()endreturn M-- 2. 使用局部变量限制作用域dolocal helper function() end-- 只在代码块内有效end-- 3. 使用注释文档--- 计算两个数的和-- param a number 第一个数-- param b number 第二个数-- return number 和function add(a, b)return a bend---## 十三、与 Cocos2d-x 集成### 13.1 Cocos2d-x Lua 绑定lua-- 创建精灵local sprite cc.Sprite:create(player.png)self:addChild(sprite)-- 动作local moveTo cc.MoveTo:create(2, cc.p(100, 100))sprite:runAction(moveTo)-- 事件监听local listener cc.EventListenerTouchOneByOne:create()listener:registerScriptHandler(function(touch, event)print(Touch began)return trueend, cc.Handler.EVENT_TOUCH_BEGAN)---### 13.2 热更新lua-- 使用 require 加载模块local gameModule require(game.module)-- 热更新时重新加载package.loaded[game.module] nillocal gameModule require(game.module)---### 13.3 与 C 交互lua-- 调用 C 函数通过绑定local result cppModule.cppFunction(arg1, arg2)-- 传递表到 Clocal data {name player,score 100}cppModule.processData(data)---## 十四、总结### 14.1 Lua 核心特性| 特性 | 说明 ||------|------|| **简洁** | 语言核心小易于学习 || **高效** | 针对性能优化 || **可扩展** | 完整的 C API || **可嵌入** | 轻松集成到应用程序 || **跨平台** | 纯 C 实现 || **协程** | 内置协作式多任务 || **元表** | 强大的元编程能力 || **垃圾回收** | 自动内存管理 |---### 14.2 学习资源| 资源 | 链接 ||------|------|| **官方网站** | https://lua.org || **参考手册** | https://www.lua.org/manual/5.4/ || **Programming in Lua** | https://www.lua.org/pil/ || **Lua 用户维基** | https://lua-users.org/wiki/ || **Cocos2d-x Lua 文档** | https://docs.cocos.com/ |--- **学习完成时间**: 2026 年 3 月 14 日 **参考版本**: Lua 5.4 **下一步**: 将 Lua 知识应用到 Cocos2d-x 游戏开发中---*报告生成完毕* ✅
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2417166.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!