Lua中的数据类型——table
table 进阶
在数据类型-table中提到 : “粗浅的理解可将table视作 array 与 map 的合体” ;
更准确的来说应该是 : “table是Lua中用于构建不同数据类型的类型, 如 array 与 map 等” .
甚至Lua中的module, package, Object这些概念都是基于table所构建的 , table在Lua中的重要性可见一斑 .
成员方法 : 与string一样 , Lua也提供了table类 , 其包含了许多成员方法用于方便的操作table .
对table的使用方式
- 作为Array使用
- 作为Map使用
- 作为Module与Package使用
- 作为Object使用
table的引用赋值
Lua中table的赋值实质的引用 , 若两个table变量同时引用了同一块资源 , 当删除一个变量时资源不会被删除 .
只有最后一个引用该资源的变量被删除了 , 资源才会被释放 .
将 table 用作 array
使用table时不指定元素的key , 并且使用[]
来选定元素 , 即可实现 array 的功能 .
Lua table 使用关联型数组 , 可在一个数组中插入不同类型的值(nil除外) . 同时其也是不定长的 , 可任意扩充内容 .
(将table用作array在使用上更像使用C++STL中的vector)
示例 (Code/tableLua/arrayTable.lua)
1 | -- 数组测试 |
输出
将 table 作为 map
使用table时以键值对的形式存入元素 , 并用.
来指定特定key的value , 即可实现 map 的功能 .
Lua中table底层设计参考了散列表 , 因此其键值对在容器中是无序的 . 使用上更接近C++中的unordered_map .
示例 (Code/tableLua/mapTable.lua)
1 | local map = {} -- 创建字典 |
输出
将 table 作为 Module 与 Package
将模块/包的相关属性与方法放入同一个table中 , 使用.
调用 , 即可实现模块与包的功能 .
在Lua中 , function 是数据类型的一种 , 同时 table 允许存入不同类型的变量 .
将以上两种特性结合一下 , 即可使用 table 实现模块与包的功能 .
创建模块
- 在单独的lua文件中创建一个table
module = {}
- 写入该模块的常量与函数
module.constant = xxx
/function module.fun() xxx end
- 返回该table
return module
加载模块
- Lua模块 : 使用
require('模块名')
或require '模块名'
加载Lua模块 - C包 : 使用
package.loadlib("路径")
加载模块 , 使用assert(模块)
打开模块
示例 (Code/tableLua/moduleTable.lua 与 testModule.lua)
moduleTable.lua
1 | -- 自定义模块 module |
testModule.lua
1 | require "moduleTable" -- 加载模块 |
testModule.lua输出
将 table 作为 Object
Lua中 , 模块与包的功能也可基于table实现 , 同样的也可以利用table实现对象的功能 .
但基于现有的知识还不能完全实现对象的功能 :
- 虽然可以通过table封装变量与方法 , 但无法实现类的实例化 (或者说只能对类操作 , 无法对对象操作)
- 当学习过 Metatable 元表 后 , 即可配合元表实现 类与对象的功能 了, 进一步还可以实现OOP .
table成员方法
Lua提供了table类 , 其有很多实用的成员方法提供对表的操作 . (这里的table不是代指某一字符串 , 而是一个类叫做table)
table.concat(list, [sep], [i], [j])
元素拼接 : 列表list
中所有元素都是字符串或数字 , 返回字符串 list[i]
到list[j]
, 中间间隔sep
.
(sep
缺省nil, i
缺省1, j
缺省#list)
1 | local tab = {"123", 456, "789"} |
table.insert(list, pos, value)
插入元素 : 往表list
的pos
位置插入一个值为value
的元素 , 无返回值 .
1 | local tab = {123, 789} |
table.remove(list, [pos])
删除元素 : 删除表list
中pos
位置的元素 , 返回被删除的值
. (pos
缺省#list , 即最后一个 , 只能是数字)
1 | local tab = {k1="v1", 123, k2="v2", 456} |
table.sort(list, [comp])
表排序 : 将表list
根据函数comp
的规则排序 , 无返回值 .
(comp
为两个参数返回值为boolean的函数 , 类似C++STL中的仿函数 , 缺省值是一个顺序排序的函数)
1 | local tab = {3, 1, 4, 2} |
table.pack(…) (Lua 5.2新增)
包装表 : 将所有参数作为值依次填入新表并返回 , 并在最后增加一个键值对 n : 参数个数
1 | local newTab = table.pack("v1", 123, "v2", 456) |
table.unpack(list, [i], [j]) (Lua 5.2新增)
拆分表 : 返回表list
中位置从i
到j
的元素的值 . (list
内元素不变)
(i
缺省1, j
缺省#list)
1 | local tab = {3, 1, 4, 2} |
table.move(a1, f, e, t, [a2]) (Lua 5.3新增)
移动元素 : 将表a1
中索引从f
到e
的元素 , 移动到表a2
索引为t
的位置之后 , 无返回值 .
(a2
缺省a1
)
1 | local tab = {123, 456, 789} |
table.maxn(table) (Lua 5.2弃用)
获取最大值 : 返回表table
的最大正数索引,如果表没有正数索引,则返回零。