4、Lua 表(table)和元表(Metatable)

版权声明:https://blog.csdn.net/weixin_40811410 https://blog.csdn.net/weixin_40811410/article/details/82116777

一、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方法

猜你喜欢

转载自blog.csdn.net/weixin_40811410/article/details/82116777