1.__index(补充)
这是metatable中常用的键,它可以是表或者函数。
当我们查找主表中不存在(若存在则返回主表成员)的成员时,会调用元表的__index索引。若没有指定,即使元表中存在要查找的成员,也会返回nil;若指定一个表,则会在指定的表中查找。
如果给__index指定一个函数,则会执行函数
Lua查找元素的规则如下:
①在表中查找,找到则返回,找不到则继续
②判断是否有元表,没有返回nil,有则继续
③判断元表有无__index方法,如果该方法为nil,则返回nil;如果是一个表,则重复①②③;如果是一个函数,则返回函数的返回值(table和key会作为参数传递进去)。
2.__newindex
如果我们给表中不存在的字段赋值的时候,则会调用__newindex。
上面我们提到如果在表中查询表中不存在的键时会调用__index,但是给表中不存在的字段赋值时依然不会出现错误。此时会调用该处提到的元方法。
看个例子:
此处给__newindex赋予了一个函数,会传入三个参数:table,key,和想要赋的值value。
注意:如果没有设置__newindex,则会在表中创建一个对应的字段(非元表)。
依旧是代码:
由此可见它在newTable这个表中创建了对应的name字段,也因此解释了后面模拟类与对象时多个对象相同属性有不同的值。
下面看当__newindex为一个表时会有什么样的作用:
在赋值(newTable.name = “kkk”)时,由于newTable没有此字段,会调用__newindex,因给他赋值thirdTable,所以会在thirdTable中查找name字段,查找到返回再进行赋值操作,这也就是为什么thirdTable中name字段会改变的原因了。
总结一下__newindex用法:
①如果__newindex是一个函数,在给table不存在的字段赋值时,会调用此函数。
②如果__newindex是一个表,在给table不存在的字段赋值时,会给表中的相应字段赋值。(即便key在此表中事先并不存在)。
③若未设置__newindex,会在一开始的表中创建对应的字段。
另外:元方法可以给总表设置,也可以给元表设置。但上面在查询和赋值时都是调用元表的元方法。
|
请发表评论