一、Lua table(表)
table 是 Lua 的一种数据结构,能容纳任何数据类型,如:数字、字典等。
Lua table 使用关联型数组,你可以用任意类型的值来作数组的索引,但这个值不能是 nil。
Lua table 是不固定大小的,你可以根据自己需要进行扩容。
Lua也是通过table来解决模块(module)、包(package)和对象(Object)的。
例如string.format表示使用”format”来索引table string。
1、table(表)的构造
table是Lua最复杂最强大的数据结构,构造器是创建和初始化表的表达式。表是Lua特有的功能强大的东西。最简单的构造函数是{},用来创建一个空表。可以直接初始化数组:
- (1)
-- 初始化表
mytable = {}
-- 指定值
mytable[1]= "Lua"
-- 移除引用
mytable = nil
-- lua 垃圾回收会释放内存
- (2)初始化一个table
local a = {["x"] = 12, ["mutou"] = 99, [3] = "hello"}
print(a["x"]);
table间的元素用逗号分隔,[“x”] = 12代表构造一个table元素,下标为”x”,值为12。
- (3)简洁的方式
local a = {x = 12, mutou = 99, [3] = "hello"}
print(a["x"]); 或 print(a.x);
对于字符串下标,可以省略方框和双引号,但是数字下标不可以
- (4)table的table
local a = {
{x = 1, y = 2},
{x = 3, y = 10}
}
调用第一个表的x元素:a[1].x
当我们为 table a 并设置元素,然后将 a 赋值给 b,则 a 与 b 都指向同一个内存。如果 a 设置为 nil ,则 b 仍然能访问 table 的元素。如果没有指定的变量指向a(即b也设置为nil时),Lua的垃圾回收机制会清理相对应的内存。
2、table(表)的遍历(pairs 和 ipairs区别)——pairs 可以替代ipairs
ipairs 和pairs在lua中都是遍历tbale的函数但是两者有区别
1、pairs遍历table中的所有的key-vale 而ipairs会根据key的数值从1开始加1递增遍历对应的table[i]值
2、pairs可以遍历表中所有的key,并且除了迭代器本身以及遍历表本身还可以返回nil;但是ipairs则不能返回nil,只能返回数字0,如果遇到nil则退出。它只能遍历到表中出现的第一个不是整数的key
a = {[1] = "a1", [2] = "a2", [3] = "a3", [5] = "a4", [6] = "a5",}
for key, value in ipairs(a) do
print(key, value)
end
结果:
1 a1
2 a2
3 a3
```
```
a = {[1] = "a1", [2] = "a2", [3] = "a3", [5] = "a4", [6] = "a5",}
for key, value in pairs(a) do
print(key, value)
end
结果:
6 a5
2 a2
3 a3
1 a1
5 a4
二、元表(Metatable)
1、元表概述
table元表等同于继承中的父类,使得Lua能够实现面向对象
在 Lua table 中我们可以访问对应的key来得到value值,但是却无法对两个 table 进行操作。
因此 Lua 提供了元表(Metatable),允许我们改变table的行为,每个行为关联了对应的元方法。
例如,使用元表我们可以定义Lua如何计算两个table的相加操作a+b。
当Lua试图对两个表进行相加时,先检查两者之一是否有元表,之后检查是否有一个叫”__add”的字段,若找到,则调用对应的值。”__add”等即时字段,其对应的值(往往是一个函数或是table)就是”元方法”。
有两个很重要的函数来处理元表:
setmetatable(table,metatable):
对指定table设置元表(metatable),如果元表(metatable)中存在__metatable键值,setmetatable会失败 。
getmetatable(table): 返回对象的元表(metatable)。
以下实例演示了如何对指定的表设置元表:
mytable = {} -- 普通表
mymetatable = {} -- 元表
__index = mymetatable ;
setmetatable(mytable,mymetatable) -- 把 mymetatable 设为 mytable 的元表
2、__index 元方法
当你通过键来访问 table 的时候,如果这个键没有值,那么Lua就会寻找该table的metatable(假定有metatable)中的__index 键。如果__index包含一个表格,Lua会在表格中查找相应的键。
3、__newindex 元方法
__newindex 元方法用来对表更新,__index则用来对表访问 。
- (1)当给一个表中不存在的索引进行赋值时,解释器就会查找__newindex 元方法,存在__newindex 元方法则调用该函数而不进行赋值操作。
- (2)如果对已存在的索引键(key1),则会进行赋值,而不调用元方法 __newindex。
mymetatable = {}
mytable = setmetatable({key1 = "value1"}, { __newindex = mymetatable })
print(mytable.key1)
mytable.newkey = "新值2"
print(mytable.newkey,mymetatable.newkey)
mytable.key1 = "新值1"
print(mytable.key1,mymetatable.newkey1)
以上实例执行输出结果为:
value1
nil 新值2 --新的索引,所以不赋值;调用__newindex方法
新值1 nil --已存在的索引,所以进行赋值;不调用__newindex方法