首先我们先看下面的代码 运行结果如下 上述我们就更改了原表的行为方法 当我们访问表中的一个元素不存在时,则会去寻找 __index 元方法,如果存在则会返回结果,否则返回nil 运行结果如下 当给你的表中不存在的key进行赋值时,lua解释器则会寻找__newindex 元方法,发现存在该方法,则执行该方法进行赋值,通过rawset来进行赋值操作 输出Yuan Bo rawget是为了绕过__index而出现的,还是上面的代码 输出的nil 此时输出了nil,如果__newindex里面这样的呢? 则会报如下错误 __index 和 __newindex的区别,__index是直接取表的值,没有对应的key,则根据__index返回,__newindex主要用于表不存在的key的赋值操作。元表的概念
local t = {}
t.prototype = {
x = 100,
y = 100,
width = 50,
height = 50
}
t.mt = {}
function t.new(value)
setmetatable(value, t.mt)
return value
end
t.mt.__index = t.prototype
t.mt.__newindex = function(table, key, value)
if key == "tomyuan" then
rawset(table, key, "Yes")
end
end
-- 处理
local instance = t.new({x = 33, y = 33})
instance.tomyuan = "YuanBo"
print(instance.tomyuan)
print(instance.x)
print(instance.y)
print(instance.width)
print(instance.height)
Yes
33
33
50
50
__index
local t = {}
t.prototype = {
x = 100,
y = 100,
width = 50,
height = 50
}
t.mt = {}
function t.new(tb)
setmetatable(tb, t.mt)
return tb
end
--
t.mt.__index = function(tb, key)
if key == "TomYuan" then
return "YuanBo"
else
return "Other"
end
end
--
local instance = t.new({
x = 100,
y = 100
})
print(instance.TomYuan)
print(instance.x)
print(instance.width)
YuanBo
100
Other
__newindex
local t = {}
t.prototype = {
x = 100,
y = 100,
width = 50,
height = 50
}
t.mt = {}
function t.new(tb)
setmetatable(tb, t.mt)
return tb
end
t.mt.__newindex = function(tb, key, value)
if key == "TomYuan" then
rawset(tb, key, "Yuan Bo")
end
end
--
local instance = t.new({
x = 100,
y = 100
})
instance.TomYuan = "Who"
print(instance.TomYuan)
rawget和rawset
local t = {}
t.prototype = {
x = 100,
y = 100,
width = 50,
height = 50
}
t.mt = {}
function t.new(tb)
setmetatable(tb, t.mt)
return tb
end
t.mt.__newindex = function(tb, key, value)
if key == "TomYuan" then
rawset(tb, key, "Yuan Bo")
end
end
--
local instance = t.new({
x = 100,
y = 100
})
instance.TomYuan = "Who"
print(rawget(instance ,instance.TomYuan))
针对rawset,如果我们上面代码这么写local t = {}
t.prototype = {
x = 100,
y = 100,
width = 50,
height = 50
}
t.mt = {}
function t.new(tb)
setmetatable(tb, t.mt)
return tb
end
t.mt.__newindex = function(tb, key, value)
if key == "TomYuan" then
tb.key = "Yuan Bo"
end
end
--
local instance = t.new({
x = 100,
y = 100
})
instance.TomYuan = "Who"
print(instance.TomYuan)
t.mt.__newindex = function(tb, key, value)
tb.key = "Yuan Bo"
end
stack traceback:
/usercode/file.lua:15: in function '__newindex'
/usercode/file.lua:15: in function '__newindex'
/usercode/file.lua:15: in function '__newindex'
/usercode/file.lua:15: in function '__newindex'
/usercode/file.lua:15: in function '__newindex'
/usercode/file.lua:15: in function '__newindex'
/usercode/file.lua:15: in function '__newindex'
/usercode/file.lua:15: in function '__newindex'
/usercode/file.lua:15: in function '__newindex'
/usercode/file.lua:15: in function '__newindex'
...
/usercode/file.lua:15: in function '__newindex'
/usercode/file.lua:15: in function '__newindex'
/usercode/file.lua:15: in function '__newindex'
/usercode/file.lua:15: in function '__newindex'
/usercode/file.lua:15: in function '__newindex'
/usercode/file.lua:15: in function '__newindex'
/usercode/file.lua:15: in function '__newindex'
/usercode/file.lua:15: in function '__newindex'
/usercode/file.lua:15: in function '__newindex'
/usercode/file.lua:23: in main chunk