lua 关于__index,__newindex的理解
2017-06-15 16:10
567 查看
table存在两种行为:查询和修改(赋值),我们可以通过元方法__index和__newindex来改变table的这两种行为。
__index主要用于table的查询
table[key] 的访问过程,首先检查table表中是否存在key的字段,如果有则返回,否则检查是否有__index的元方法,没有返回nil,有则查找元方法。
__index元方法可以是不一定是一个函数,还可以是一个table。如果是一个函数,则以table和不存在的key作为参数方位该函数,
例如:__index = function(t,key)
如果是一个table时,就以相同的方式来访问这个table(即传入key访问元方法的table,如果存在则放回值,反之返回nil)
例如:__index = tab --此时会返回tab[key]的值
__index可以很好的实现具有默认值的table
function setDefaultValues(t,d)
local mt = {__index = function() return d end}
setmetatable(t, mt)
end
tab = {x=10,y=20}
print(tab.x ,tab.y,tab.z) --由于没有设置元方法则为nil
setDefaultValues(tab,100) --设置默认值(设置__index元方法)
print(tab.z) --检查到有__index的元方法则返回默认值但是这种设置默认值的弊端是如果很多表都需要设置默认值,则需要创建很多元表,所以更有的做法是让元表公有,其原理类似
local mt = {__index = function(t) return t.___ end}
function setDefaultValues(t,d)
t.___= d
setmetatable(t, mt)
e__newindex主要用于table的更新
在书上用了简短一段话来描述__newindex
“当对table中不存在的索引赋值时,解释器就会查找__newindex元方法。如果有这个元方法,就调用这个元方法,而不是执行复制。如果这个元方法是一个table,解释器就在table中进行复制,而不是对原来的table。”
不得不说此处高能
1)当对table中不存在的索引赋值时,解释器就会查找__newindex元方法
这句话不难理解,顾名思义
2)如果有这个元方法,就调用这个元方法,而不是执行复制。
我们需要代码来验证这句话的含义:
local mt = {
__newindex = function (table,key,value)
print("newindex被无情地调用了")
end
}
local t = {}
setmetatable(t, mt)
t[1] = 20
for k,v in pairs(t) do
print(k ,v)
end输出结果:
newindex被无情地调用了
[Finished in 0.1s]
看的出t中不存在任何值,很多blog中有这样一段替换上面的mt():
local mt = {
__newindex = function (table,key,value)
rawset(table, key, 2)
end
}输出结果:
3)如果这个元方法是一个table,解释器就在table中进行复制,而不是对原来的table。
local k = {}
local mt = {
__newindex = k
}
local t = {}
setmetatable(t, mt)
print("赋值前:")
for k,v in pairs(k) do
print(k ,v)
end
t[1] = 20
print("赋值后:t表中的值:")
for k,v in pairs(t) do
print(k ,v)
end
print("赋值后:k表中的值:")
for k,v in pairs(k) do
print(k ,v)
end
输出结果:
__index主要用于table的查询
table[key] 的访问过程,首先检查table表中是否存在key的字段,如果有则返回,否则检查是否有__index的元方法,没有返回nil,有则查找元方法。
__index元方法可以是不一定是一个函数,还可以是一个table。如果是一个函数,则以table和不存在的key作为参数方位该函数,
例如:__index = function(t,key)
如果是一个table时,就以相同的方式来访问这个table(即传入key访问元方法的table,如果存在则放回值,反之返回nil)
例如:__index = tab --此时会返回tab[key]的值
__index可以很好的实现具有默认值的table
function setDefaultValues(t,d)
local mt = {__index = function() return d end}
setmetatable(t, mt)
end
tab = {x=10,y=20}
print(tab.x ,tab.y,tab.z) --由于没有设置元方法则为nil
setDefaultValues(tab,100) --设置默认值(设置__index元方法)
print(tab.z) --检查到有__index的元方法则返回默认值但是这种设置默认值的弊端是如果很多表都需要设置默认值,则需要创建很多元表,所以更有的做法是让元表公有,其原理类似
local mt = {__index = function(t) return t.___ end}
function setDefaultValues(t,d)
t.___= d
setmetatable(t, mt)
e__newindex主要用于table的更新
在书上用了简短一段话来描述__newindex
“当对table中不存在的索引赋值时,解释器就会查找__newindex元方法。如果有这个元方法,就调用这个元方法,而不是执行复制。如果这个元方法是一个table,解释器就在table中进行复制,而不是对原来的table。”
不得不说此处高能
1)当对table中不存在的索引赋值时,解释器就会查找__newindex元方法
这句话不难理解,顾名思义
2)如果有这个元方法,就调用这个元方法,而不是执行复制。
我们需要代码来验证这句话的含义:
local mt = {
__newindex = function (table,key,value)
print("newindex被无情地调用了")
end
}
local t = {}
setmetatable(t, mt)
t[1] = 20
for k,v in pairs(t) do
print(k ,v)
end输出结果:
newindex被无情地调用了
[Finished in 0.1s]
看的出t中不存在任何值,很多blog中有这样一段替换上面的mt():
local mt = {
__newindex = function (table,key,value)
rawset(table, key, 2)
end
}输出结果:
1 2 [Finished in 0.1s]从以上两段代码的输出我们不难看出元表中存在__newindex方法的时候对表t某个不存在的索引的赋值,直接调用的元方法,至于具体赋什么值真的是没关系
3)如果这个元方法是一个table,解释器就在table中进行复制,而不是对原来的table。
local k = {}
local mt = {
__newindex = k
}
local t = {}
setmetatable(t, mt)
print("赋值前:")
for k,v in pairs(k) do
print(k ,v)
end
t[1] = 20
print("赋值后:t表中的值:")
for k,v in pairs(t) do
print(k ,v)
end
print("赋值后:k表中的值:")
for k,v in pairs(k) do
print(k ,v)
end
输出结果:
赋值前: 赋值后:t表中的值 赋值后:k表中的值 1 20 [Finished in 0.1s]不难看出赋值前,k是空表,赋值后k表中输出了值 key:1 value:20 而t表依旧为空。
相关文章推荐
- lua 之__index/__newindex的理解
- 理解Lua语言中的__index,__newindex,rawget和rawset
- 理解Lua语言中的__index,__newindex,rawget和rawset 标签: luametatable__index__newindexrawget 2013-09-27 20:02
- lua 之__index/__newindex的理解
- Lua中__index 和__newindex 讲解
- 关于jquery--index()方法的简单理解
- [Lua]用__index/__newindex来限制访问
- Lua中__index和__newindex实践
- 了解Lua语言中的_index,newindex,rawget和rawset
- 关于position定位及z-index的理解
- 深入理解关于Lua与C数据通信的栈
- 关于lua元表和元方法的例子 自己理解了并加了一些注释
- 了解Lua语言中的_index,newindex,rawget和rawset
- 了解Lua语言中的_index,newindex,rawget和rawset
- Lua中__index和__newindex之间的沉默与合作
- Lua的__index和__newindex之间的沉默与合作
- 搜索引擎 lucene2 关于Field类中的内部类Store和Index的理解
- 了解Lua语言中的_index,newindex,rawget和rawset
- 了解Lua语言中的_index,newindex,rawget和rawset
- lua中查找表的过程已经(以及对元表和__index方法的理解)