Lua 核心知识点详解
文章目录
- Lua 核心知识点详解
- 一、变量与作用域
- (一)全局变量与局部变量
- (二)示例
- 二、函数
- (一)函数定义
- (二)函数调用
- (三)正则相关函数
- 三、表(table)
- (一)基本操作
- (二)元表与元方法
- (三)表的遍历
- 四、模块与包
- (一)模块创建
- (二)模块加载
- 五、协程(coroutine)
- (一)协程创建与状态
- (二)协程操作
- 六、字符串操作
- (一)基础操作
- (二)模式匹配与处理
- 七、与 C 交互
Lua 核心知识点详解
在 Lua 学习过程中,从基础的变量、函数到进阶的表、协程等,每个知识点都有其独特之处。下面将对这些核心知识点进行详细梳理。
一、变量与作用域
(一)全局变量与局部变量
- 全局变量:直接声明,如
a = 1
,在整个程序范围内可见,存储在_G
表中,可通过_G.变量名
访问。 - 局部变量:使用
local
声明,如local b = 2
,仅在声明的作用域(如代码块、函数内)有效,更安全且访问效率高,能降低命名冲突风险。
(二)示例
-- 全局函数
function globalFunc()print("全局函数")
end-- 局部函数
local function localFunc()print("局部函数")
end-- 作用域内调用(正常)
globalFunc() -- 输出:全局函数
localFunc() -- 输出:局部函数-- 在作用域外尝试调用(假设以下代码在另一个作用域,如函数或 do...end 块内)
globalFunc() -- 正常调用(全局可见)
-- localFunc() -- 报错:localFunc 未定义(局部不可见)
二、函数
(一)函数定义
Lua 函数有两种定义方式:
-- 方式一
function funcName(arg1, arg2)-- 函数体return result
end-- 方式二
funcName = function(arg1, arg2)-- 函数体return result
end
还支持可变参数(...
),可通过 select
函数获取可变参数。
(二)函数调用
- 普通调用:
funcName(1, 2)
。 - 方法调用(面向对象风格):通过
:
调用,会自动将调用者作为第一个参数传递,如obj:method()
等价于obj.method(obj)
。
(三)正则相关函数
以 string.find
、string.match
等为例,可进行模式匹配,支持类似正则式的模式(如 %d
匹配数字、%l
匹配小写字母等)。示例:
local s = "abcd1234.abccc"
print(s:find("%."))
local pattern = "^[0-7%l%-]*$"
local test1 = "a3-7b"
print(string.match(test1,pattern))
三、表(table)
(一)基本操作
- 创建:
local t = {}
。 - 增删元素:
- 数组式:
t[1] = "a"
,table.insert(t, "b")
(插入),table.remove(t, 1)
(删除)。 - 字典式:
t["key"] = "value"
。
- 数组式:
- 长度:
#t
获取表的长度(数组部分)。
(二)元表与元方法
元表(metatable)用于修改表的默认行为,通过 setmetatable
设置。元方法是元表中以 __
开头的键,如 __add
(加法元方法)、__index
(索引元方法,用于处理表中不存在的键)、__newindex
(新索引元方法,用于控制表的赋值)。示例:
local t = {a = 15}
local mt = {__add = function(a, b)return a.a + bend,__index = {abc = 123}
}
setmetatable(t, mt)
print(t + 1) -- 调用__add元方法
print(t["abc"]) -- 调用__index元方法
(三)表的遍历
ipairs
:遍历表的数组部分,按顺序访问,示例:local t = {1, 2, 3} for i, v in ipairs(t) doprint(i, v) end
pairs
:遍历表中所有键值对(包括数组和字典部分),顺序不确定,基于next
函数实现,示例:t = {apple = "a",banana = "b",erasen = "c",water = "d" } for i,j in pairs(t) doprint(i,j) end
next
:用于获取表中指定键的下一个键值对,可模拟pairs
遍历,示例:t = { a = 1, b = 2, c = 3, d = 4} print(next(t)) print(next(t,"a")) print(next(t,"b")) print(next(t,"c")) print(next(t,"d"))
四、模块与包
(一)模块创建
将变量、函数等放入一个表中,然后返回该表,示例(module.lua
):
local module = {}
module.index = 1
function module.sum(a, b)return a + b
end
return module
(二)模块加载
使用 require
加载模块,require "module"
会查找并运行 module.lua
,返回模块表。加载后可调用模块中的函数或访问变量,示例:
local mod = require("module")
print(mod.index)
print(mod.sum(1, 2))
require
具有缓存机制,同一模块只会加载一次,且查找路径由 package.path
控制,其特点有运行指定文件、末尾不带扩展名、目录层级用“.”分隔、只会运行一次、从 package.path
中的路径里查找等。
五、协程(coroutine)
(一)协程创建与状态
- 创建:
coroutine.create(func)
,返回协程对象。 - 状态:
coroutine.status(co)
可查看协程状态(suspended
挂起、running
运行、dead
死亡等)。
(二)协程操作
- 启动/恢复:
coroutine.resume(co, ...)
,可传递参数给协程。 - 暂停:
coroutine.yield(...)
,在协程内暂停,返回值可被resume
获取,同时resume
传递的参数会成为yield
的返回值,实现协程与外部的双向通信。示例:
local co = coroutine.create(function(a, b)print("协程开始,初始参数:", a, b)local yield_ret1 = coroutine.yield("暂停中...")print("第一次恢复后,yield返回值:", yield_ret1)local yield_ret2 = coroutine.yield("又暂停了...")print("第二次恢复后,yield返回值:", yield_ret2)return "协程结束"
end)
local success, ret = coroutine.resume(co, 10, 20)
print("第一次resume返回:", success, ret)
success, ret = coroutine.resume(co, "继续运行")
print("第二次resume返回:", success, ret)
success, ret = coroutine.resume(co, "完成")
print("第三次resume返回:", success, ret)
- 简化创建:
coroutine.wrap(func)
,返回一个函数,调用该函数可启动协程,更简洁但错误处理不如create
灵活。
六、字符串操作
(一)基础操作
- 长度:
#s
或s:len()
。 - 字符与字节转换:
string.char(...)
(字节转字符)、string.byte(s, i, j)
(字符转字节)。字符串在内存中是连续的字节存储,可存储任何Byte
值,包括不可见字符,且每个字符有正数和负数序号两种索引方式。示例:
local s = string.char(0x30, 0x00, 0x31, 0x32, 0x33)
local n = string.byte(s, 2)
print(n, #s)
(二)模式匹配与处理
使用 string.find
、string.match
、string.gsub
等函数进行模式匹配和替换,支持丰富的模式规则。示例:
local s = "abcd34565431234.11%abccc"
print(s:find("d[%d%.]+"))
print(s:gsub("%d","x"))
七、与 C 交互
Lua 可通过 string.pack
和 string.unpack
进行二进制数据的打包与解包,用于与 C 程序交互,处理二进制协议等。示例:
local data = string.pack(">L", 1) -- 打包为大端 32 位无符号整数
local r = string.unpack(">L", data) -- 解包
print(r)
以上就是 Lua 核心知识点的详细介绍,掌握这些内容能帮助我们更好地运用 Lua 进行开发。