核心知识点:Lua 运算符、字符串库、表工具、闭包、模块 require 完整笔记;Lua 算术 / 关系 / 逻辑运算符;and‑or 模拟三目运算符;字符串库全套 API;表底层引用特点;table 库(insert/remove/sort/concat);闭包原理;迭代器底层;模块、require/dofile/loadfile 区别;LuaGC 三色标记回收;模拟面向对象封装基础
一、Lua 运算符
1 概念
Lua 运算符分为算术运算符、关系运算符、逻辑运算符、其他运算符;注意 Lua 没有++ -- += -=这类自增复合赋值。
2 特性 & 规则
-
算术运算符 :
+ - * / % ^;^幂运算(次方),负号-; -
关系运算符 :
> < >= <= == ~=;⚠️不等于是~=,不是!=; -
逻辑运算符
and or notand:a and b,a 为真返回 b;a 为假返回 a
or:a or b,a 为真返回 a;a 为假返回 b
not:取反,返回布尔
逻辑运算不一定返回布尔值,可以返回原始数据;只有
false/nil判定为假,其余全部为真。 -
模拟三目运算符 :Lua 没有
?:三目,使用条件 and 真值 or 假值;前提:真值不能为 nil/false。 -
其他运算符
#:获取字符串 / 连续数组表长度;下标不连续表结果不准;..:字符串拼接; -
运算符优先级(从高到低):幂运算
^→ 负号 /not →* / %→+ -→..拼接 → 比较运算符> < == ~=→and→or。
3 语法 & 代码片段
-- and or示例
local a = 1
local b = 2
print(a and b) -- 2
print(a or b) --1
--模拟三目:1>2为false,输出2
local res = (1>2) and 1 or 2
print(res)
4 相关知识点对比
C 系三目运算符 VS Lua and‑or 模拟三目
C:条件?a:b;a、b 可以任意值;
Lua:条件 and a or b;a 不能是 nil/false,否则逻辑出错。
5 模块拓展
利用 and‑or 做参数默认值。
二、字符串标准库 string.*
1 概念
Lua 内置 string 库,提供大小写转换、替换、查找、反转、格式化、ASCII 转换、模式匹配等全套字符串工具。
2 特性 & 规则
-
string.upper(s):全部转为大写 -
string.lower(s):全部转为小写 -
string.gsub(原串,匹配串,替换串[,替换次数]):字符串替换;第四个参数控制替换次数,缺省全部替换;返回替换后字符串 + 替换总次数。 -
string.find(s,pattern[,start]):查找子串;可指定起始查找下标;Lua 字符串下标从 1 开始;找到返回起始、结束索引;找不到返回 nil。 -
string.reverse(s):字符串反转。 -
string.format():格式化,语法类似 C 语言 printf,%d %s占位符。 -
string.char(asc):ASCII 码转字符;范围 0‑255。 -
string.byte(s[,index]):字符取 ASCII 码,可指定位置。 -
string.len(s)/#s:获取字符串长度,两种写法等价。 -
string.rep(s,n):字符串拷贝复制 n 份拼接返回。 -
string.gmatch(s,pattern):返回迭代器,循环遍历匹配到的子串;支持模式:%a字母、%d数字,+匹配一个或多个。
转义字符
\n \r \t继承 C 语言规则。
3 语法 & 代码片段
local s = "hello world"
print(string.upper(s))
local new,count = string.gsub("aaaaa","a","z",1)
print(string.find(s,"o"))
print(string.format("hp=%d",100))
print(string.char(97))
print(string.byte("abc",1))
for word in string.gmatch(s,"%a+") do
print(word)
end
4 相关知识点对比
#`获取长度 VS `string.len()
字符串:两者等价;
table:#只统计从 1 开始连续整数数组;不连续下标结果错误。
5 模块拓展
Lua 模式匹配(简易正则)做配表文本解析。
三、table 底层引用特性
1 概念
table 在 Lua 中是引用类型;变量保存内存引用,不是拷贝数据;多个变量赋值同一个 table,指向同一块内存。
2 特性 & 规则
-
tab2 = tab1:不会复制表,两个变量指向同一块内存;修改其中一个,另一个同步变化。 -
设置
tab[key]=nil:删除表内该键;不会立刻释放内存,等待 GC 回收。 -
Lua GC 为三色标记清除算法:黑 = 存活不回收;灰 = 待扫描;白 = 可回收;变量置 nil 切断引用,GC 自动回收内存。
3 语法 & 代码片段
local t1 = {name="test"}
local t2 = t1
t2.name = "abc"
print(t1.name) --输出abc,同内存引用
t1 = nil
-- t2依然持有引用,内存不会回收
4 相关知识点对比
值类型 VS table 引用类型
number/boolean/string:赋值拷贝值;
table:赋值拷贝内存地址,共享同一份数据。
5 模块拓展
深拷贝、浅拷贝 table 工具函数。
四、table 库工具函数
1 概念
table.concat / table.insert / table.remove / table.sort / table.getn,专门操作数组形式 table。
2 特性 & 规则
-
table.concat(t[,sep][,start][,end]):把数组内元素拼接字符串;sep 分隔符,可指定起止下标。 -
table.insert(t[,pos],value):不写 pos 默认尾部插入;指定 pos 在该下标插入,后面元素后移。 -
table.remove(t[,pos]):不写 pos 默认删除尾部元素;指定 pos 删除对应下标,后续元素前移。 -
table.sort(t[,compFunc]):数组排序;默认升序;传入匿名比较函数可实现降序、自定义排序。 -
table.getn(t): 计算长度。
3 语法 & 代码片段
local arr = {3,1,7,4}
table.sort(arr,function(a,b) return a>b end) --降序
print(table.concat(arr,"#"))
table.insert(arr,2,99)
table.remove(arr,1)
table.getn(arr)
4 相关知识点对比
手动遍历增删 VS table 库函数
手写:需要自己处理元素移位;
table 库:内部完成下标移位,适合数组 table。
5 模块拓展
Lua 配表大量使用 table,游戏热更新配表可以直接写 Lua table。
五、闭包函数(Closure)
1 概念
闭包 = 外部函数 + upvalue(上值,外部函数局部变量) + 内部嵌套函数;函数内部可以定义嵌套函数;内部函数可以访问外部函数的局部变量(upvalue)。
2 特性 & 规则
-
C 语言不允许函数内嵌套函数;Lua 支持。
-
外部函数执行结束,局部变量本应销毁,但是被内部闭包捕获 (upvalue),变量依然存活。
-
闭包经常用来手写自定义迭代器(模拟 ipairs/pairs)。
3 语法 & 代码片段(手写简易迭代器闭包)
local function MyIter(t)
local index = 0
local cnt = #t
return function()
index = index + 1
if index <= cnt then
return index,t[index]
else
return nil
end
end
end
local tb = {"a","b","c"}
for i,v in MyIter(tb) do
print(i,v)
end
4 相关知识点对比
普通函数 VS 闭包
普通函数:变量生命周期跟随函数调用;调用结束局部变量销毁;
闭包:内部函数捕获外部局部变量,变量生命周期被延长。
5 模块拓展
XLua 回调、状态保存大量使用闭包。
六、泛型 for 迭代器底层原理
1 概念
for k,v in iter_func in t do end泛型 for 底层执行 5 步:
-
计算
in后面表达式,得到 3 返回值:迭代函数、状态常量、控制变量; -
将状态常量、控制变量传入迭代函数;
-
迭代函数返回值赋值给 for 的变量列表;
-
如果第一个返回值为 nil,循环直接结束;不为 nil 执行循环体;
-
重复调用迭代函数,继续循环。
2 特性 & 规则
ipairs/pairs 本质就是返回这套三元组的迭代器函数。
3 相关知识点对比
ipairs/pairs 见上午笔记。
4 模块拓展
手写自定义迭代器遍历特殊配表。
七、模块与脚本加载:require /dofile/loadfile
1 概念
模块一般就是一个 table,内部存放变量、函数;实现类似类封装效果;三种脚本加载方式。
2 特性 & 规则
-
dofile(filename):每次调用,读取并完整执行脚本;无缓存;重复调用重复执行。
-
loadfile(filename) :仅读取编译脚本,不执行;返回函数,手动调用才执行代码。
-
require(filename)【项目最常用】:有缓存;第一次加载执行脚本;后续再次 require,直接返回缓存结果,不会重复执行脚本;防止重复执行。
模块内部变量不加 local 就是全局变量,会污染全局命名空间;模块尽量所有成员加 local,对外只暴露 table。
3 语法 & 代码片段
-- mymod.lua
local mymod1 = {}
function mymod1.Test()
print("模块函数")
end
return mymod1
-- 使用方脚本
local m = require("mymod")
m.Test()
4 相关知识点对比
dofile VS loadfile VS require
dofile:读入立刻执行,无缓存,重复执行;
loadfile:只编译不运行,需要手动调用返回函数;
require:带缓存,只执行一次,业务开发首选。
5 模块拓展
Lua 配表写成模块,打包 AB 包完成配表热更新。
八、Lua 模拟面向对象基础:封装
1 概念
Lua 没有 class 关键字;利用 table+local 私有变量,模拟面向对象封装:私有变量 local 不对外暴露;对外 table 提供公开 get/set 函数访问私有数据。
2 特性 & 规则
-
local 修饰的变量是模块内私有,外部脚本无法直接访问;
-
通过模块 table 内的公开函数读取、修改私有变量,完成封装;
-
后续元表 metatable 实现继承、多态。
3 语法 & 代码片段
local PersonModule = {}
--私有变量
local _hp = 100
--公开接口
function PersonModule.GetHp()
return _hp
end
function PersonModule.SetHp(val)
_hp = val
end
return PersonModule
4 相关知识点对比
C# class 原生封装 VS Lua table 模拟封装
C#:public/private 关键字原生支持访问控制;
Lua:没有访问修饰符;依靠 local 私有 + 对外 table 接口约定实现封装。
综合拓展
1 当日完整知识链路 运算符(and‑or 模拟三目) → string 库字符串处理 → table 引用类型、GC 三色标记 → table 库增删改排序 → 闭包捕获 upvalue → 泛型 for 迭代器底层 → require/dofile/loadfile 模块加载 → table 模拟面向对象封装。 2 高频易错清单
-
不等于写
!=,Lua 必须写~=; -
and‑or 模拟三目,真值不能是 nil/false;
-
table 赋值是引用,不是拷贝;
-
#只适合连续整数下标数组; -
dofile 重复执行脚本;业务优先用 require;
-
不加 local 变量全部是全局,命名冲突覆盖;
-
闭包捕获外部 local 变量,变量生命周期延长。
3 核心考点 Lua 逻辑运算符 and/or 规则、and‑or 模拟三目、string 库常用 API、table 引用类型、GC 三色标记、闭包 upvalue、泛型 for 迭代器底层、require/dofile/loadfile 三者区别、Lua 模拟封装。
4 进阶拓展学习方向 元表 metatable、**index/**newindex、Lua 模拟继承多态、XLua 与 C# 交互。