Lua 核心知识点详解

发布于:2025-09-10 ⋅ 阅读:(20) ⋅ 点赞:(0)

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.findstring.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 + b
    end,
    __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) do
        print(i, v)
    end
    
  • pairs:遍历表中所有键值对(包括数组和字典部分),顺序不确定,基于 next 函数实现,示例:
    t = {
        apple = "a",
        banana = "b",
        erasen = "c",
        water = "d"
    }
    for i,j in pairs(t) do
        print(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 灵活。

六、字符串操作

(一)基础操作

  • 长度:#ss: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.findstring.matchstring.gsub 等函数进行模式匹配和替换,支持丰富的模式规则。示例:

local s = "abcd34565431234.11%abccc"
print(s:find("d[%d%.]+"))
print(s:gsub("%d","x"))

七、与 C 交互

Lua 可通过 string.packstring.unpack 进行二进制数据的打包与解包,用于与 C 程序交互,处理二进制协议等。示例:

local data = string.pack(">L", 1)  -- 打包为大端 32 位无符号整数
local r = string.unpack(">L", data)  -- 解包
print(r)

以上就是 Lua 核心知识点的详细介绍,掌握这些内容能帮助我们更好地运用 Lua 进行开发。


网站公告

今日签到

点亮在社区的每一天
去签到