lua table如何删除成员 lua清空table_初始化


文章目录

  • 一、table表
  • 1. 表的构造
  • 2. 表的操作
  • (1) concat(连接)
  • (2) insert(插入)
  • (3) remove(移除)
  • (4) sort(排序)
  • (5) maxn(最大值)
  • 二、模块与包
  • 1. require
  • 2. 加载机制
  • 3. C包


一、table表

  • table 是一种数据结构用来帮助我们创建不同的数据类型(数组、字典等)。
  • table 使用关联型数组,可以用任意类型的值来作数组的索引,不可是nil。
  • table 不固定大小。

Lua 也是通过table来解决模块(module)、包(package)和对象(Object)的。

1. 表的构造

构造器是创建和初始化表的表达式。最简单的构造函数是{},用来创建一个空表。

mytable = {} -- 初始化表
mytable[1] = 'lua' -- 指定值
mytable = nil -- 移除引用
-- lua 垃圾回收会释放内存

创建table a并设置元素,将a赋值给b,则a与b都指向同一个内存。如果a设置为nil,则b同样能访问table的元素。如果没有的变量指向这片内存,Lua的垃圾回收机制才会清理这片内存。


2. 表的操作

lua table如何删除成员 lua清空table_lua table如何删除成员_02

(1) concat(连接)

a = {'a', 'b', 'c'}
print(table.concat(a))
print(table.concat(a, ", "))
print(table.concat(a, " <-> ", 2, 3))
abc
a, b, c
b <-> c

(2) insert(插入)

a = {'A', 'B'}
table.insert(a, 'C')
print(a[3])  --> C

在索引为 1 处插入

a = {'A', 'B'}
table.insert(a, 1, 'C')
for k, v in pairs(a) do
    print(v)
end

运行结果:

C
A
B

(3) remove(移除)

  • 默认删除table最后一位。
a = {'A', 'B', 'C'}
table.remove(a)
for k, v in pairs(a) do
    print(v)
end
--[[
A
B
--]]
  • 指定删除索引为 1 的,后续元素前移。
a = {'A', 'B', 'C'}
table.remove(a, 1)
for k, v in pairs(a) do
    print(v)
end
--[[
B
C
--]]

(4) sort(排序)

a = {'c', 'd', 'b', 'a'}
table.sort(a)
for _, v in ipairs(a) do
    print(v)
end
a
b
c
d

(5) maxn(最大值)

table.maxn 在 Lua5.2 之后该方法已经不存在了,我们定义了 table_max 方法来实现。

function table_max(a)
    local mx = nil
    for k, v in pairs(a) do
        if mx == nil then mx = v end
        if mx < v then mx = v end
    end
    return mx
end

table = {[1] = 1, [3] = 3, [4] = 8, [10] = -1}
print(table_max(table))
-- 8

二、模块与包

模块类似于一个封装库,从 Lua 5.1 开始,Lua 加入了标准的模块管理机制,可以把一些公用的代码放在一个文件里,以 API 接口的形式在其他地方调用,有利于代码的重用和降低代码耦合度。

Lua 的模块是由变量、函数等已知元素组成的 table,因此创建一个模块很简单,就是创建一个 table,然后把需要导出的常量、函数放入其中,最后返回这个 table 就行。以下为创建自定义模块 module.lua,文件代码格式如下:

-- module.lua
-- 创建空表
module = {}
-- 常量
module.constant = "const"
-- 公有函数
function module.func1()
    io.write("public func")
end
-- 私有函数
local function func2()
    print('private func')
end

function module.func3()
    func2()
end

return module

模块的结构就是一个 table 的结构,因此可以像操作调用 table 里的元素那样来操作调用模块里的常量或函数。

上面的 func2 声明为程序块的局部变量,即表示一个私有函数,因此是不能从外部访问模块里的这个私有函数,必须通过模块里的公有函数来调用。


1. require

Lua提供了一个名为require的函数用来加载模块。

require("模块名")

或者

require "模块名"

执行 require 后会返回一个由模块常量或函数组成的 table,并且还会定义一个包含该 table 的全局变量。

require "module"

print(module.constant)
-- const
module.func3()
-- private func

起别名

local m = require "module"

print(m.constant)
m.func3()

2. 加载机制

  • 对于自定义的模块,模块文件不是放在哪个文件目录都行,函数 require 有它自己的文件路径加载策略,它会尝试从 Lua 文件或 C 程序库中加载模块。
  • require 用于搜索 Lua 文件的路径是存放在全局变量 package.path 中,当 Lua 启动后,会以环境变量 LUA_PATH 的值来初始这个环境变量。如果没有找到该环境变量,则使用一个编译时定义的默认路径来初始化。

3. C包

Lua和C是很容易结合的,使用 C 为 Lua 写包。

与Lua中写包不同,C包在使用以前必须首先加载并连接,在大多数系统中最容易的实现方式是通过动态连接库机制

Lua在一个叫 loadlib 的函数内提供了所有的动态连接的功能。这个函数有两个参数:库的绝对路径初始化函数

local path = "/usr/local/lua/lib/libluasocket.so"
local f = loadlib(path, "luaopen_socket")

loadlib 函数加载指定的库并且连接到 Lua,然而它并不打开库(也就是说没有调用初始化函数),反之他返回初始化函数作为 Lua 的一个函数,这样我们就可以直接在Lua中调用他。


如果加载动态库或者查找初始化函数时出错,loadlib 将返回 nil 和错误信息。我们可以修改前面一段代码,使其检测错误然后调用初始化函数:

local path = "/usr/local/lua/lib/libluasocket.so"
-- 或者 path = "C:\\windows\\luasocket.dll",这是 Window 平台下
local f = assert(loadlib(path, "luaopen_socket"))
f()  -- 真正打开库

一般情况下我们期望二进制的发布库包含一个与前面代码段相似的 stub 文件,安装二进制库的时候可以随便放在某个目录,只需要修改 stub 文件对应二进制库的实际路径即可。

将 stub 文件所在的目录加入到 LUA_PATH,这样设定后就可以使用 require 函数加载 C 库了。