Lua:基础

基础

函数

1-- 定义一个函数
2local function foo()
3    print("foo")
4end
5
6-- 调用函数
7foo()

变长参数

 1-- 定义一个函数
 2local function foo(...)
 3    print(...)
 4end
 5
 6--- 求和
 7local function sum(...)
 8    local s = 0
 9    for _, v in ipairs({...}) do
10        s = s + v
11    end
12    return s
13end

多返回值

1-- 定义一个函数
2local function foo()
3    return 1, 2, 3
4end
5
6-- 调用函数
7local a, b, c = foo()

Metatable

Metatable 元数据表,它可以用来改变 Lua 的默认行为。它通过重载全局操作符,从而改变全局操作符的行为,实现更复杂的功能。

通过元表,可以把table 的索引“__index”设置为一个函数,这样,当 table 中没有某个索引时,就会调用这个函数来返回一个值,而不会报错。这样就可以在 table 中进行更复杂的操作,比如模拟实现一个类的继承机制。

下面是一个具体的例子:

 1-- 创建一个父类
 2local parent = {
 3    foo = "foo"
 4}
 5
 6-- 创建一个子类
 7local child = {
 8    bar = "bar"
 9}
10
11-- 设置 child 的 metatable
12setmetatable(child, {
13    __index = parent
14})
15
16-- 打印 child.foo
17print(child.foo)
18-- 输出:foo
19
20-- 打印 child.bar
21print(child.bar)
22-- 输出:bar

上面的代码中,我们创建了一个父类 parent,一个子类 child,并将 child 的 metatable 设置为 parent。这样,当 child 中没有某个索引时,就会自动从 parent 中查找,从而实现了类似继承的功能。

数组

Lua 中的数组是一种特殊的 table,它的索引是从 1 开始的连续整数。Lua 中的数组不需要预先声明,只要给数组赋值,就会自动创建数组。

1-- 创建一个数组
2local arr = {
3    "a",
4    "b",
5    "c"
6}

上面的代码中,我们创建了一个数组 arr,它的索引是从 1 开始的连续整数,这样,我们就可以通过索引来访问数组中的元素。

1-- 打印数组的第一个元素
2print(arr[1])
3-- 输出:a
4-- 获取长度
5print(#arr)
6-- 输出:3

迭代器

迭代器是一种特殊的函数,它可以用来遍历集合中的元素。迭代器的返回值是一个函数,这个函数可以用来遍历集合中的元素。

 1-- 创建一个数组
 2local arr = {
 3    "a",
 4    "b",
 5    "c"
 6}
 7
 8-- 创建一个迭代器
 9local iter = function(arr, index)
10    index = index + 1
11    local value = arr[index]
12    if value then
13        return index, value
14    end
15end
16
17-- 遍历数组
18for index, value in iter, arr, 0 do
19    print(index, value)
20end
21
22-- 输出:
23-- 1 a
24-- 2 b
25-- 3 c

Table

Table 是 Lua 中最重要的数据结构,它是一种关联数组,可以把它看成是一个字典或者对象。

table.insert(table, [pos,] value)

  • 在 table 的 pos 位置插入 value,如果 pos 为 nil,则插入到 table 的末尾。

table.concat(list: table, sep?: string, i?: integer, j?: integer)

  • 作用:table.concat 函数用于将 table 中的元素连接成一个字符串。

  • 参数:

    • list:指定要连接的 table。

    • sep:指定连接的分隔符,可选参数,默认为 “"。

    • i:指定连接的起始位置,可选参数,默认为 1。

    • j:指定连接的结束位置,可选参数,默认为 table 的长度。

  • 返回值:返回连接后的字符串。

  • 例子:

1local list = {1, 2, 3, 4, 5}
2local str = table.concat(list, ",")
3-- str = "1,2,3,4,5"

基本内置函数

function assert(v, message, ...) end

  • 检查第一个参数 v 是否为 true,如果为 false,则抛出错误,错误信息为第二个参数 message,后面的参数用于格式化 message。

function collectgarbage(opt, arg) end

  • 控制 Lua 的垃圾收集器。opt 有以下几种取值:
    • collect:执行一次完整的垃圾收集循环。这个函数可能会调用 __gc 元方法。

    • count:返回 Lua 使用的内存总量(以 K 字节为单位)。

    • restart:重启垃圾收集器的自动运行。

    • setpause:将 arg 设为收集器的 间歇率(以百分比表示)。

    • setstepmul:将 arg 设为收集器的 步进倍率(必须大于 1)。

    • step:单步运行垃圾收集器。收集器步进“间歇率”百分比的内存。如果你传入了非 0 值,收集器步进的相当于内存的 arg 百分比。如果收集器结束一个循环将返回 true。

    • stop:停止垃圾收集器的自动运行。

function dofile(filename) end

  • 从文件 filename 中加载并运行一个 Lua 块。返回所有块的返回值。与 loadfile 不同的是,dofile 不接受环境参数。

function error(message, level) end

  • 抛出一个错误。错误信息为 message,level 为错误的级别。默认情况下,level 为 1,即错误发生的地方。如果 level 为 2,错误发生的地方是调用 error 的地方。

function getfenv(f) end

  • 返回函数 f 的环境变量。如果 f 为 0,返回当前线程的环境变量。如果 f 为一个数字,返回全局环境变量。

function getmetatable(object) end

  • 返回对象 object 的元表。

function ipairs(t) end

  • 返回三个值:迭代函数、表 t、0。迭代函数每次调用返回 t 的下一个索引和对应的值。

function load(chunk,chunkname,mode,env)

  • 作用:加载一个 Lua 代码块,并返回该代码块的值。

  • 参数:

    • chunk:一个字符串或者是一个函数,它代表了要加载的 Lua 代码块

    • chunkname:一个字符串,表示 chunk 的名字,用于错误报告

    • mode:一个字符串,表示 chunk 的模式,可以是 “bt”(或者 “b”)表示以二进制形式加载;“t”(或者 “txt”)表示以文本形式加载

    • env:一个表,表示 chunk 加载的环境,如果是 nil,则使用全局环境。

  • 返回值:

    • 成功:加载的块的返回值(可能有多个)

    • 失败:nil 和错误描述

  • 例子:

1local result = load("return 1+2", "example", "t", _G)
2print(result()) -- 3

function loadfile(filename, mode, env) end

  • 加载文件

function loadstring(text, chunkname) end

  • 加载字符串

function newproxy(proxy) end

  • 作用:创建一个新的代理,可以用来模拟用户自定义数据类型。

  • 参数:proxy是一个可选参数,用来创建一个代理。

  • 返回值:返回一个新的代理,可以用来模拟用户自定义数据类型。

  • 例子:

 1local proxy = newproxy(true)
 2local mt = getmetatable(proxy)
 3
 4mt.__index = function(table, key)
 5    print("indexing " .. key)
 6    return 0
 7end
 8
 9print(proxy.x)
10-- 输出:indexing x
11-- 0

该例子中,使用newproxy函数创建了一个新的代理,然后使用getmetatable获取了该代理的元表,并设置了__index字段,当试图访问proxy.x时,就会调用__index函数,从而打印出indexing x,并返回0

function module(name, ...) end

  • 作用:module 函数用于定义一个模块,该模块可以在其他模块中使用。

  • 参数:name 是模块名称,… 表示可变参数,可以是一系列函数或变量。

  • 返回值:无

  • 例子:

1module('mymodule') 
2function add(a, b)
3 return a + b
4end

该例子定义了一个名字为“mymodule”的模块,并在模块中定义了一个名为“add”的函数,该函数接收两个参数并返回它们的和。

然后在另一个文件中,可以使用 require 函数来加载这个模块,然后通过 mymodule.add 来调用这个函数。代码如下:

1local mymodule = require('mymodule')
2local result = mymodule.add(4, 5)
3-- result 的值为 9

function next(table, index) end

  • 作用:模拟迭代器。返回表中的一个键值对,当 index 为 nil 时,返回第一个键值对;当 index 为最后一个键值对的键时,返回 nil 。

  • 参数:table 是待检索的表格,index 是表格中的键。

  • 返回值:返回下一个键值对,形式为 key-value 对,key 为键,value 为值。

  • 例子:

 1local myTable = {1, 2, 3, 4, 5}
 2local index = 1
 3while true do
 4    local key, value = next(myTable, index)
 5    if key == nil then
 6        break
 7    end
 8    index = key
 9    print(value)
10end
  • 解释:上述例子中,我们使用 next 函数循环遍历 myTable 表中的每一个值,并将其打印出来。

function pairs(t) end

  • 作用:pairs 函数返回用来遍历指定表(table)中所有的 key 值和 value 的迭代函数,以及当前遍历的控制变量。

  • 参数:t 表示要遍历的表。

  • 返回值:返回一个迭代函数,以及初始遍历控制变量。

  • 例子:

1local t = {a = 1, b = 2, c = 3}
2for k, v in pairs(t) do
3  print(k, v)
4end
5
6-- 输出:
7-- a 1
8-- b 2
9-- c 3

function pcall(f, arg1, ...) end

  • 作用:pcall 函数用于保护模式调用一个函数,如果调用成功,返回 true 和函数的返回值;如果调用失败,返回 false 和错误信息。

  • 参数:f 表示要调用的函数,arg1 表示传递给函数的第一个参数,... 表示传递给函数的其他参数。

  • 返回值:返回一个布尔值和函数的返回值。

  • 例子:

function print(...) end

  • 作用:print 函数用于打印指定的内容。

function rawequal(v1, v2) end

  • 作用:rawequal 函数用于比较两个值是否相等,不会调用元方法。

function rawget(table, index) end

  • 作用:rawget 函数用于获取表中指定索引的值,不会调用元方法。

function rawlen(v) end

  • 作用:rawlen 函数用于获取表中元素的数量,不会调用元方法。

function rawset(table, index, value) end

  • 作用:rawset 函数用于设置表中指定索引的值,不会调用元方法。

function select(index, ...) end

  • 功能:select 函数用于从可变参数列表中选出指定索引位置的参数。

  • 参数:index:表示需要选取的参数的索引位置,从 1 开始计数。...:可变参数列表。

  • 返回值:返回索引位置 index 对应的参数值。

  • 实例:

1local a, b, c = select(2, 'foo', 'bar', 'baz')
2-- a = 'bar'
3-- b = 'baz'
4-- c = nil
  • 例子2:
1function foo(...)
2    local arg = {...}
3    for i = 1, select('#', ...) do
4        print(arg[i])
5    end
6end

上面的例子中,由于 select 的第一个参数是 #,因此 select('#', ...) 表示获取可变参数列表的长度。

如果第一个参数是数字,那么 select 函数会返回指定索引位置的参数值。

1function foo(...)
2    local arg = {...}
3    local arg2 = {select(2, ...)} -- 从第二个参数开始选取
4end

function setfenv(f, table) end

  • 作用:setfenv函数用来设置函数环境。

  • 参数:

    • f:需要设置环境的函数。

    • table:新的函数环境。

  • 返回值:setfenv函数返回设置后的函数对象。

  • 例子:

 1-- 创建一个函数
 2function foo()
 3    print(x)
 4end
 5
 6-- 创建一个环境
 7env = {x=5}
 8
 9-- 设置函数的环境
10setfenv(foo,env)
11
12foo() -- 输出 5

function setmetatable(table, metatable) end

  • 作用:setmetatable 函数用于设置表的元表。

function tonumber(e) end

  • 作用:tonumber 函数用于将字符串转换为数字。

function tostring(v) end

  • 作用:tostring 函数用于将值转换为字符串。

function type(v) end

  • 作用:type 函数用于获取值的类型。

  • 参数:v 表示要获取类型的值。

  • 返回值:返回值的类型,类型可能是:nilbooleannumberstringtablefunctionthreaduserdata

function warn(message, ...) end

  • 作用:warn 函数用于打印警告信息。

function xpcall(f, msgh, arg1, ...) end

  • 作用:xpcall 函数用于在捕获异常时运行函数。

  • 参数:

    • f:要调用的函数

    • msgh:在错误发生时调用的函数

    • arg1:f 函数的第一个参数

    • …:f 函数的其他参数

  • 返回值:xpcall 函数返回一个布尔值,表示函数是否调用成功。

  • 例子:

1local function main()
2  -- do something
3end
4
5local function onError(err)
6  print(err)
7end
8
9xpcall(main, onError)
  • 例子:在这个例子中,xpcall 函数调用 main 函数,如果发生错误,则会调用 onError 函数,并将错误信息作为参数传入 onError 函数。

function unpack(list, i, j) end

  • 作用:返回 list 中索引从 i 到 j 的所有值,如果缺少参数,将默认设置 i 为 1,j 为 list 的长度。

  • 参数说明

    • list:指定要解包的 table

    • i:起始索引,可选参数,默认为 1

    • j:结束索引,可选参数,默认为 list 的长度

  • 返回值:返回 list 中索引从 i 到 j 的所有值

  • 例子和解释

    1list = {1, 2, 3, 4, 5, 6, 7}
    2
    3-- 从索引 2 开始解包 list
    4result = unpack(list, 2)
    5-- result = 2, 3, 4, 5, 6, 7
    6
    7-- 从索引 2 到索引 5 解包 list
    8result = unpack(list, 2, 5)
    9-- result = 2, 3, 4, 5
    

String

string.byte(s, i, j)

  • 作用:string.byte 函数用于返回字符串中指定位置的字符的 ASCII 码。

  • 参数:

    • s:指定要获取 ASCII 码的字符串。

    • i:指定要获取 ASCII 码的字符的索引,可选参数,默认为 1。

    • j:指定要获取 ASCII 码的字符的结束索引,可选参数,默认为 i。

  • 返回值:返回字符串中指定位置的字符的 ASCII 码。

  • 例子:

1local str = "hello world"
2local code = string.byte(str, 1, 5)
3-- code = 104, 101, 108, 108, 111

string.find(s, pattern, init, plain)

  • 作用:string.find 函数用于在字符串中查找指定的字符串。

  • 参数:

    • s:指定要查找的字符串。

    • pattern:指定要查找的字符串。

    • init:指定查找的起始位置,可选参数,默认为 1。

    • plain:指定是否使用纯文本查找,可选参数,默认为 false。

  • 返回值:返回一个 table,包含查找到的字符串的起始位置和结束位置。

  • 例子:

1local str = "hello beautiful world"
2--           1 3 5 7 9 1 3 5 7 9 1
3local result = string.find(str, "be")
4-- result = {7, 9}

string.sub(s, i, j)

  • 作用:string.sub 函数用于返回字符串中指定位置的子字符串。

  • 参数:

    • s:指定要获取子字符串的字符串。

    • i:指定要获取子字符串的起始位置,可选参数,默认为 1。

    • j:指定要获取子字符串的结束位置,可选参数,默认为字符串的长度。

  • 返回值:返回字符串中指定位置的子字符串。

  • 例子:

1local str = "hello world"
2local sub = string.sub(str, 1, 5)
3-- sub = hello

Debug

debug.getinfo(level, flags)

  • 作用:debug.getinfo 函数用于获取函数的信息。

  • 参数:

    • level:指定函数的层级,0 表示当前函数,1 表示调用当前函数的函数,以此类推。

    • flags:指定要获取的信息

      • n:函数的名字。获取之后放到 namenamewhat 字段中

      • S:函数的源代码信息

      • l:函数的当前行号。获取之后放到 currentline 字段中

      • f:函数本身

      • u:函数的上级函数

      • L:函数的局部变量