Lua 基础语法(二)

核心知识点:Lua 运算符、字符串库、表工具、闭包、模块 require 完整笔记;Lua 算术 / 关系 / 逻辑运算符;and‑or 模拟三目运算符;字符串库全套 API;表底层引用特点;table 库(insert/remove/sort/concat);闭包原理;迭代器底层;模块、require/dofile/loadfile 区别;LuaGC 三色标记回收;模拟面向对象封装基础

一、Lua 运算符

1 概念

Lua 运算符分为算术运算符、关系运算符、逻辑运算符、其他运算符;注意 Lua 没有++ -- += -=这类自增复合赋值。

2 特性 & 规则

  1. 算术运算符+ - * / % ^^幂运算(次方),负号-

  2. 关系运算符> < >= <= == ~=;⚠️不等于是~=不是!=

  3. 逻辑运算符 and or not

    and:a and b,a 为真返回 b;a 为假返回 a

    or:a or b,a 为真返回 a;a 为假返回 b

    not:取反,返回布尔

    逻辑运算不一定返回布尔值,可以返回原始数据;只有false/nil判定为假,其余全部为真。

  4. 模拟三目运算符 :Lua 没有?:三目,使用条件 and 真值 or 假值;前提:真值不能为 nil/false。

  5. 其他运算符

    #:获取字符串 / 连续数组表长度;下标不连续表结果不准;

    ..:字符串拼接;

  6. 运算符优先级(从高到低):幂运算^ → 负号 /not → * / %+ -..拼接 → 比较运算符> < == ~=andor

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 ba 不能是 nil/false,否则逻辑出错

5 模块拓展

利用 and‑or 做参数默认值。

二、字符串标准库 string.*

1 概念

Lua 内置 string 库,提供大小写转换、替换、查找、反转、格式化、ASCII 转换、模式匹配等全套字符串工具。

2 特性 & 规则

  1. string.upper(s):全部转为大写

  2. string.lower(s):全部转为小写

  3. string.gsub(原串,匹配串,替换串[,替换次数]):字符串替换;第四个参数控制替换次数,缺省全部替换;返回替换后字符串 + 替换总次数。

  4. string.find(s,pattern[,start]):查找子串;可指定起始查找下标;Lua 字符串下标从 1 开始;找到返回起始、结束索引;找不到返回 nil。

  5. string.reverse(s):字符串反转。

  6. string.format():格式化,语法类似 C 语言 printf,%d %s占位符。

  7. string.char(asc):ASCII 码转字符;范围 0‑255。

  8. string.byte(s[,index]):字符取 ASCII 码,可指定位置。

  9. string.len(s) / #s:获取字符串长度,两种写法等价。

  10. string.rep(s,n):字符串拷贝复制 n 份拼接返回。

  11. 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 特性 & 规则

  1. tab2 = tab1:不会复制表,两个变量指向同一块内存;修改其中一个,另一个同步变化。

  2. 设置tab[key]=nil:删除表内该键;不会立刻释放内存,等待 GC 回收

  3. 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 特性 & 规则

  1. table.concat(t[,sep][,start][,end]):把数组内元素拼接字符串;sep 分隔符,可指定起止下标。

  2. table.insert(t[,pos],value):不写 pos 默认尾部插入;指定 pos 在该下标插入,后面元素后移。

  3. table.remove(t[,pos]):不写 pos 默认删除尾部元素;指定 pos 删除对应下标,后续元素前移。

  4. table.sort(t[,compFunc]):数组排序;默认升序;传入匿名比较函数可实现降序、自定义排序。

  5. 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 特性 & 规则

  1. C 语言不允许函数内嵌套函数;Lua 支持。

  2. 外部函数执行结束,局部变量本应销毁,但是被内部闭包捕获 (upvalue),变量依然存活。

  3. 闭包经常用来手写自定义迭代器(模拟 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 步:

  1. 计算in后面表达式,得到 3 返回值:迭代函数、状态常量、控制变量;

  2. 将状态常量、控制变量传入迭代函数;

  3. 迭代函数返回值赋值给 for 的变量列表;

  4. 如果第一个返回值为 nil,循环直接结束;不为 nil 执行循环体;

  5. 重复调用迭代函数,继续循环。

2 特性 & 规则

ipairs/pairs 本质就是返回这套三元组的迭代器函数。

3 相关知识点对比

ipairs/pairs 见上午笔记。

4 模块拓展

手写自定义迭代器遍历特殊配表。

七、模块与脚本加载:require /dofile/loadfile

1 概念

模块一般就是一个 table,内部存放变量、函数;实现类似类封装效果;三种脚本加载方式。

2 特性 & 规则

  1. dofile(filename):每次调用,读取并完整执行脚本;无缓存;重复调用重复执行。

  2. loadfile(filename) :仅读取编译脚本,不执行;返回函数,手动调用才执行代码。

  3. 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 特性 & 规则

  1. local 修饰的变量是模块内私有,外部脚本无法直接访问;

  2. 通过模块 table 内的公开函数读取、修改私有变量,完成封装;

  3. 后续元表 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 高频易错清单

  1. 不等于写!=,Lua 必须写~=

  2. and‑or 模拟三目,真值不能是 nil/false;

  3. table 赋值是引用,不是拷贝;

  4. #只适合连续整数下标数组;

  5. dofile 重复执行脚本;业务优先用 require;

  6. 不加 local 变量全部是全局,命名冲突覆盖;

  7. 闭包捕获外部 local 变量,变量生命周期延长。

3 核心考点 Lua 逻辑运算符 and/or 规则、and‑or 模拟三目、string 库常用 API、table 引用类型、GC 三色标记、闭包 upvalue、泛型 for 迭代器底层、require/dofile/loadfile 三者区别、Lua 模拟封装。

4 进阶拓展学习方向 元表 metatable、**index/**newindex、Lua 模拟继承多态、XLua 与 C# 交互。

相关推荐
王的宝库1 小时前
GO常用标准库包
开发语言·后端·golang
geovindu1 小时前
python: Face Recognition
开发语言·后端·python·人脸识别
平头哥技术团队1 小时前
Day 13 | 调 line-height 和 margin:三处间距让名片页脱离模板感
开发语言·前端·javascript·学习·html5
黑马程序员毕设2 小时前
基于Java的仪器管理系统设计与实现
java·开发语言·spring boot·后端·微信小程序
平头哥AI2 小时前
Day 13 | 一个函数回两个值:Go 的 error 是从哪冒出来的
开发语言·后端·golang
asdzx672 小时前
Python 实现 PDF 文本查找与高亮标注
开发语言·python·pdf
zander2582 小时前
LeetCode 1143. 最长公共子序列
开发语言·python·算法
Sumerking2 小时前
llc_control.c 专项评审(v3 更新版)
c语言·开发语言·算法·obc
棣廷2 小时前
初识Python面向对象
java·开发语言