我自己学习后总结一下lua元表中的__index 和 __newindex(如果有错误,请大神指出,虚心求教)
1.__index
主要功能:1.返回一个默认的值代替nil(__index是一个function)(这里解释下什么是默认的值如下)
local test = {}
print(test.x)--这里默认是返回nil
--如果设置元表__index
local mt = {}
mt.__index = function()
return 20
end
setmetatable(test,mt)
print(test.x)--20 这里就设置了返回默认值20就把nil给代替了。
2.返回一个表中没有固定key 的值(这里的__index是一个表)
local test = {}
print(test.x)--这里默认是返回nil
--如果设置元表__index
local mt = {}
mt.__index = {x = 20}
setmetatable(test,mt)
print(test.x)--20 这里直接查询了__index中的x
print(test.y)--nil 这里__index中没有
总结一下__index的功能,就是查询一个表中的数据,如果该表中没有就去元表中__index中查找,如果__index是一个表,那么查找这个表中有无该数据,没有返回nil;如果__index是一个function 那么就是返回该方法的返回值。
2.__newindex
主要功能:1.设置表的权限不允许修改表中数据。
(1)如果__newindex是一个表
local newindex = {}
local mt = {}
mt.__newindex = newindex
--一个新表
local test = {}
test.x = 1
print(test.x)--1,这个时候可以在表中增添数据
setmetatable(test, mt)
test.y = 2
print(test.y)--nil,这个时候表中没有数据
print(newindex.y)--因为这个2赋值给了newindex表中
--(这个功能就是利用一个表向另一个表中赋值~但是本表数据没有改表)
(2)如果__newindex是一个函数
local newindex = function ( )
print("sorry,cannot change anything")
end
local mt = {}
mt.__newindex = newindex
--一个新表
local test = {}
test.x = 1
print(test.x)--1,这个时候可以在表中增添数据
setmetatable(test, mt)
test.y = 2
print(test.y)--nil,这个时候表中没有数据
--(这个功能就是禁止给表中修改任何数据)
--*******
--在这里注意一个问题
test.x = 33
print(test.x) --33, 这里是不会掉用到__newindex的方法的因为该表中已经有了该字段
--输出结果:
--[[
1
sorry,cannot change anything
nil
33
--]]
2.增加修改表中数据并且留存更改信息
local newindex = function ( tb,key,value )
--tb[key] = value --这里会导致重复掉用__newindex进入死循环
--此处可以记录一下更改数据的时间
print("新增一个"..key.."字段","值为"..value)
rawset(tb, key, value)
end
local mt = {}
mt.__newindex = newindex
local test = {}
setmetatable(test, mt)
test.x = 1
print(test.x) --1
--上面说过在增加字段的时候,会掉用元表__newindex的方法,所以这里主要是以rawset来设置表的字段