Lua


13. 标准库 (Standard Libraries)


文档摘要

标准库 (Standard Libraries) Lua 标准库详解与实践指南 1. 基础库 (Base Library) 基础库是 Lua 的核心,自动加载,无需显式 。它提供了解释器运行和基本操作所需的核心函数。 1.1 核心函数 : 检查 是否为真。如果为假( 或 ),则抛出一个错误,错误信息为可选的 。常用于断言,确保程序逻辑正确。 : 垃圾回收器接口。 可以是以下字符串: : 执行一次完整的垃圾回收周期。 : 返回 Lua 使用的总内存(KB)。 : 重启垃圾回收器。 : 设置暂停系数( 为百分比,默认 200)。 : 设置步进倍率( 为百分比,默认 200)。 : 停止垃圾回收器。 : 返回垃圾回收器是否正在运行。 : 切换到分代垃圾回收模式。 : 切换到增量垃圾回收模式。

13. 标准库 (Standard Libraries)

Lua 标准库详解与实践指南

1. 基础库 (Base Library)

基础库是 Lua 的核心,自动加载,无需显式 require。它提供了解释器运行和基本操作所需的核心函数。

1.1 核心函数

  • assert (v [, message]): 检查 v 是否为真。如果为假(nilfalse),则抛出一个错误,错误信息为可选的 message。常用于断言,确保程序逻辑正确。
local value = 10 assert(value > 0, "Value must be positive") -- 断言成功,程序继续执行 local name = nil -- assert(name, "Name cannot be nil") -- 断言失败,抛出错误 "Name cannot be nil"
  • collectgarbage ([opt [, arg]]): 垃圾回收器接口。opt 可以是以下字符串:

    • "collect": 执行一次完整的垃圾回收周期。

    • "count": 返回 Lua 使用的总内存(KB)。

    • "restart": 重启垃圾回收器。

    • "setpause": 设置暂停系数(arg 为百分比,默认 200)。

    • "setstepmul": 设置步进倍率(arg 为百分比,默认 200)。

    • "stop": 停止垃圾回收器。

    • "isrunning": 返回垃圾回收器是否正在运行。

    • "generational": 切换到分代垃圾回收模式。

    • "incremental": 切换到增量垃圾回收模式。

print(collectgarbage("count")) -- 打印当前内存使用量 collectgarbage("collect") -- 手动执行垃圾回收
  • dofile ([filename]): 打开并执行指定的文件。类似于 loadfile 后立即调用返回的函数。
-- 创建一个文件 test.lua,内容为: print("Hello from test.lua") dofile("test.lua") -- 执行 test.lua,输出 "Hello from test.lua"
  • error (message [, level]): 抛出一个错误。message 是错误信息,level 指定错误报告级别(默认为 1,当前函数;2,调用当前函数的函数;以此类推)。
function divide(a, b) if b == 0 then error("Division by zero", 2) -- 错误信息 "Division by zero",报告级别为调用 divide 的函数 end return a / b end function calculate() divide(10, 0) -- 这里调用了 divide end calculate() -- 运行 calculate 会抛出错误,并指出错误发生在 calculate 函数中
  • getmetatable (object): 返回对象的元表。如果对象没有元表,则返回 nil
local t = {} local mt = { __index = { a = 1 } } setmetatable(t, mt) print(getmetatable(t) == mt) -- true print(getmetatable(10)) -- nil (数字没有默认元表)
  • ipairs (t): 返回三个值:迭代函数、表 t 和初始索引 0。用于遍历数组形式的表(索引从 1 开始且连续)。
local arr = {"apple", "banana", "cherry"} for i, v in ipairs(arr) do print(i, v) -- 输出索引和值 end -- 输出: -- 1 apple -- 2 banana -- 3 cherry
  • load (chunk [, chunkname [, mode [, env]]]): 加载一个代码块。chunk 可以是字符串或函数(从函数读取代码块)。返回编译后的代码块作为函数,或者在出错时返回 nil 和错误信息。chunkname 是代码块名称(用于错误信息),mode 可以是 "b" (二进制块), "t" (文本块), 或 "bt" (两者皆可,默认)。env 是代码块的环境。
local code = "return 1 + 2" local f = load(code) print(f()) -- 输出 3 local error_code = "syntax error" local f, err = load(error_code) print(f, err) -- 输出 nil [string "=(load)"]:1: syntax error near 'error'
  • loadfile ([filename [, mode [, env]]]): 类似于 load,但从文件中读取代码块。
-- 创建一个文件 script.lua,内容为: return "Hello from script.lua" local f = loadfile("script.lua") print(f()) -- 输出 Hello from script.lua
  • next (table [, index]): 允许遍历表的所有字段。index 是前一个键(第一次调用为 nil)。返回表的下一个键和对应的值,如果没有更多元素,则返回 nil
local my_table = { a = 10, b = 20, c = 30 } local key = nil while true do key, value = next(my_table, key) if key == nil then break end print(key, value) end -- 输出顺序可能不固定,例如: -- a 10 -- b 20 -- c 30
  • pairs (t): 返回三个值:next 函数、表 tnil。用于遍历表的所有键值对,包括数组部分和哈希部分。
local my_table = { "apple", b = "banana", "cherry", d = "date" } for key, value in pairs(my_table) do print(key, value) end -- 输出顺序可能不固定,例如: -- 1 apple -- 2 cherry -- b banana -- d date
  • pcall (f [, arg1, ···]): "受保护的调用" (protected call)。调用函数 f,以保护模式运行,捕获任何错误。返回一个状态码(布尔值,true 表示成功,false 表示错误)和返回值(成功时为函数返回值,错误时为错误信息)。
function risky_function() error("Something went wrong!") end local status, result = pcall(risky_function) if not status then print("Error occurred:", result) -- 输出 Error occurred: Something went wrong! else print("Function executed successfully:", result) end
  • print (···): 打印输出参数到标准输出。
print("Hello", "world", 123) -- 输出 Hello world 123
  • rawequal (v1, v2): 原始相等性比较。不调用元方法 __eq。比较两个对象是否原始相等(引用相等)。
local t1 = { value = 1 } local t2 = t1 local t3 = { value = 1 } print(rawequal(t1, t2)) -- true (t1 和 t2 指向同一个表) print(rawequal(t1, t3)) -- false (t1 和 t3 是不同的表,即使内容相同)
  • rawget (table, index): 原始表访问。不调用元方法 __index。直接从表中获取指定索引的值。
local t = { a = 10, b = 20 } local mt = { __index = { c = 30 } } setmetatable(t, mt) print(rawget(t, "a")) -- 10 (直接访问表 t) print(rawget(t, "c")) -- nil (即使元表中有,rawget 只看表自身) print(t.c) -- 30 (通过 . 访问会触发元方法 __index,从元表查找)
  • rawset (table, index, value): 原始表设置。不调用元方法 __newindex。直接设置表中指定索引的值。
local t = {} local mt = { __newindex = function(table, key, value) print("Cannot set", key) end } setmetatable(t, mt) rawset(t, "a", 10) -- 直接设置 t.a = 10,不触发 __newindex print(t.a) -- 10 t.b = 20 -- 触发 __newindex,输出 Cannot set b,但 t.b 仍然被设置 (如果 __newindex 没有阻止) print(t.b) -- 20 (默认 __newindex 不阻止赋值)
  • select (index, ···): 访问变长参数列表。如果 index 是数字 n,返回第 n 个参数之后的所有参数;如果 index 是字符串 "#", 返回参数的总个数。
function test_select(...) print("Total arguments:", select("#", ...)) print("Second argument:", select(2, ...)) print("Arguments from 3rd onwards:", select(3, ...)) end test_select(10, 20, 30, 40) -- 输出: -- Total arguments: 4 -- Second argument: 20 -- Arguments from 3rd onwards: 30 40
  • setmetatable (table, metatable): 设置表的元表。
local t = {} local mt = { __index = { a = 1 } } setmetatable(t, mt) print(t.a) -- 1 (访问 t.a 时,由于 t 中不存在 'a',触发 __index 元方法,从元表查找)
  • tonumber (e [, base]): 将参数转换为数字。base 是进制(2-36,默认为 10)。如果无法转换,返回 nil
print(tonumber("123")) -- 123 print(tonumber("0xFF", 16)) -- 255 (十六进制) print(tonumber("abc")) -- nil (无法转换为数字)
  • tostring (v): 将参数转换为字符串。
print(tostring(123)) -- "123" print(tostring(true)) -- "true" print(tostring({})) -- "table: 0xXXXXXXXX" (表的字符串表示)
  • type (v): 返回参数的类型名称字符串。
print(type(10)) -- "number" print(type("hello")) -- "string" print(type(true)) -- "boolean" print(type({})) -- "table" print(type(function() end)) -- "function" print(type(nil)) -- "nil"
  • _VERSION: 包含当前 Lua 解释器版本号的全局变量。
print(_VERSION) -- 例如:Lua 5.4
  • xpcall (f, errh [, arg1, ···]): 类似于 pcall,但允许指定错误处理函数 errh。当 f 内部发生错误时,Lua 会调用 errh 并将原始错误对象作为参数传递给它。xpcall 返回状态码和 errh 的返回值(成功时为 f 的返回值,错误时为 errh 的返回值)。
function risky_function() error("Something went wrong!") end function error_handler(err) print("Custom error handler caught:", err) return "Handled error" -- errh 的返回值将作为 xpcall 的返回值 end local status, result = xpcall(risky_function, error_handler) if not status then print("xpcall failed, error handler returned:", result) -- 输出 xpcall failed, error handler returned: Handled error else print("xpcall succeeded:", result) end -- 同时 error_handler 中会输出: Custom error handler caught: Something went wrong!

2. 字符串库 (String Library)

字符串库提供了处理字符串的各种函数。需要使用 require "string" 加载。

  • string.byte (s [, i [, j]]): 返回字符 s[i], s[i+1], ..., s[j] 的内部数字编码。i 默认为 1,j 默认为 i
print(string.byte("Lua")) -- 76 (L 的 ASCII 码) print(string.byte("Lua", 2)) -- 117 (u 的 ASCII 码) print(string.byte("Lua", 1, 3)) -- 76 117 97 (L, u, a 的 ASCII 码)
  • string.char (···): 接收 0 个或多个整数,将每个整数转换为对应的字符,并返回由这些字符连接成的字符串。
print(string.char(76, 117, 97)) -- "Lua"
  • string.dump (function [, stripdebug]): 返回一个包含指定函数的二进制表示的字符串。可以稍后使用 loadstring 加载。stripdebug 为真时,不包含调试信息。
function add(a, b) return a + b end local dumped_func = string.dump(add) local loaded_func = loadstring(dumped_func) print(loaded_func(5, 3)) -- 8
  • string.find (s, pattern [, init [, plain]]): 在字符串 s 中查找第一个匹配 pattern 的位置。返回起始索引和结束索引,如果未找到,返回 nilinit 指定起始搜索位置(默认为 1)。plain 为真时,禁用模式匹配,进行纯文本查找。
local s = "Hello Lua world" local start, finish = string.find(s, "Lua") print(start, finish) -- 7 9 local start_plain = string.find(s, ".", 1, true) -- 纯文本查找 "." print(start_plain) -- 1 local start_pattern = string.find(s, ".") -- 模式匹配 "." (匹配任意字符) print(start_pattern) -- 1
  • string.format (formatstring, ···): 返回格式化后的字符串,类似于 C 语言的 sprintf
local name = "Alice" local age = 30 local formatted_string = string.format("Name: %s, Age: %d", name, age) print(formatted_string) -- Name: Alice, Age: 30
  • string.gmatch (s, pattern): 返回一个迭代器函数,每次调用迭代器函数都会返回字符串 s 中下一个匹配 pattern 的子串。
local s = "apple banana apple cherry" for word in string.gmatch(s, "%w+") do -- 匹配单词 print(word) end -- 输出: -- apple -- banana -- apple -- cherry
  • string.gsub (s, pattern, repl [, n]): 返回一个新的字符串,将 s 中所有(或最多 n 个)匹配 pattern 的子串替换为 replrepl 可以是字符串、表或函数。
local s = "Lua is fun. Lua is powerful." local new_s = string.gsub(s, "Lua", "Moon") print(new_s) -- Moon is fun. Moon is powerful. local s_limit = string.gsub(s, "Lua", "Moon", 1) -- 只替换第一个 print(s_limit) -- Moon is fun. Lua is powerful. local s_table_repl = string.gsub(s, "(Lua)", {Lua="Moon"}) -- 表替换,捕获组作为键 print(s_table_repl) -- Moon is fun. Moon is powerful. local s_func_repl = string.gsub(s, "(Lua)", function(match) return string.upper(match) end) -- 函数替换,捕获组作为参数 print(s_func_repl) -- LUA is fun. LUA is powerful.
  • string.len (s): 返回字符串 s 的长度。
print(string.len("Hello")) -- 5
  • string.lower (s): 返回字符串 s 的小写版本。
print(string.lower("HELLO")) -- "hello"
  • string.match (s, pattern [, init]): 在字符串 s 中查找第一个匹配 pattern 的位置。如果找到匹配,返回捕获组,否则返回 nilinit 指定起始搜索位置(默认为 1)。
local s = "Name: Alice, Age: 30" local name = string.match(s, "Name: (%w+)") -- 捕获名字 local age = string.match(s, "Age: (%d+)") -- 捕获年龄 print(name, age) -- Alice 30
  • string.pack (formatstring, ···): 将值按照格式字符串 formatstring 打包成二进制字符串。

  • string.packsize (formatstring): 返回格式字符串 formatstring 打包后的字符串大小(字节数)。

  • string.rep (s, n): 返回一个由字符串 s 重复 n 次连接而成的新字符串。

print(string.rep("abc", 3)) -- "abcabcabc"
  • string.reverse (s): 返回字符串 s 的反转版本。
print(string.reverse("hello")) -- "olleh"
  • string.sub (s, i [, j]): 返回字符串 s 的子串,从索引 i 开始到索引 j 结束(包含 ij)。j 默认为字符串末尾。索引可以是负数,表示从字符串末尾开始计数。
local s = "Hello Lua" print(string.sub(s, 1, 5)) -- "Hello" print(string.sub(s, 7)) -- "Lua" print(string.sub(s, -3)) -- "Lua" (从倒数第三个字符开始到末尾)
  • string.unpack (formatstring, s [, pos]): 按照格式字符串 formatstring 解包二进制字符串 spos 指定起始解包位置(默认为 1)。

  • string.upper (s): 返回字符串 s 的大写版本。

print(string.upper("hello")) -- "HELLO"

3. 表库 (Table Library)

表库提供操作表的函数。需要使用 require "table" 加载。

  • table.concat (list [, sep [, i [, j]]]): 连接列表 list 中从索引 ij 的元素,使用分隔符 sep(默认为空字符串)。
local list = {"apple", "banana", "cherry"} print(table.concat(list)) -- "applebananacherry" print(table.concat(list, ", ")) -- "apple, banana, cherry" print(table.concat(list, ", ", 2, 3)) -- "banana, cherry"
  • table.insert (list, [pos,] value): 在列表 list 的位置 pos 插入元素 valuepos 默认为列表末尾。
local list = {"apple", "cherry"} table.insert(list, "banana") -- 默认末尾插入 print(table.concat(list, ", ")) -- "apple, cherry, banana" table.insert(list, 2, "grape") -- 在索引 2 插入 print(table.concat(list, ", ")) -- "apple, grape, cherry, banana"
  • table.move (a1, f, e, t, a2): 将表 a1 中索引从 fe 的元素移动到表 a2 的索引 t 开始的位置。
local a1 = {1, 2, 3, 4, 5} local a2 = {10, 20, 30} table.move(a1, 2, 4, 2, a2) -- 将 a1[2...4] 移动到 a2[2...] -- a1 变为 {1, 5} -- a2 变为 {10, 2, 3, 4, 30} print(table.concat(a1, ", ")) -- "1, 5" print(table.concat(a2, ", ")) -- "10, 2, 3, 4, 30"
  • table.pack (···): 将参数打包成一个表,键从 1 开始,并添加一个字段 "n" 记录参数个数。
local packed_table = table.pack(10, 20, "hello") for i = 1, packed_table.n do print(i, packed_table[i]) end print("n:", packed_table.n) -- 输出: -- 1 10 -- 2 20 -- 3 hello -- n: 3
  • table.remove (list [, pos]): 移除并返回列表 list 中位置 pos 的元素。pos 默认为列表末尾。
local list = {"apple", "banana", "cherry"} local removed_item = table.remove(list, 2) -- 移除索引 2 的元素 "banana" print(removed_item) -- "banana" print(table.concat(list, ", ")) -- "apple, cherry" local removed_last = table.remove(list) -- 移除末尾元素 "cherry" print(removed_last) -- "cherry" print(table.concat(list, ", ")) -- "apple"
  • table.sort (list [, comp]): 对列表 list 的元素进行排序。可选的比较函数 `

发布者: 作者: 转发
评论区 (0)
U