关于Lua重要的元方法__index 和__newindex

元表和元方法是lua进行面向对象编程的很重要的方法,所以 花时间研究了一下。

(元方法,是在设置元表之后在元表中查找的方法,使用之前一定要setmetatable 或者用getmetatable检查是否有元表)

__index方法(主要是查找时)

当调用一个table的索引值不存在时,lua会查找该table的__index方法,__index方法可以是函数,也可是一个table;

举例:

local mt = {}

一 、--__index传入的是函数

mt.__index = function (table,key)

      print("key = ",key)

end

local t = {my = "i have one"}

print("这是输出1",t.myAdd)

--[LUA-print] 这是输出1   nil

setmetatable(t,mt)

print("这是输出2",t.myAdd)

--[LUA-print] key =       myAdd  --这句打印说明 程序进入了__index方法中查找
--[LUA-print] 这是输出2   nil      -- 但是__index方法中还是没有这个索引值

二 、-- __index 传入的是table

local mt = {}

local mtTable = { meta = "this is prevalue"}

mt.__index = mtTable

local t = {my = "i have one"}

print("这是输出1",t.meta)  --[LUA-print] 这是输出1   nil (普通查找key不存在 打印为空)

setmetatable(t,mt)

print("这是输出2",t.meta)--[LUA-print] 这是输出2   this is prevalue  (设置元表后,对于不存在的key进入元表查找,元表中返的table有于是输出)

 

__newindex元方法(主要是赋值时)

当给table中不存在的索引赋值时,Lua会去查找该table的__newindex方法。__newindex同样可以传入函数 或者 一个table

举例:

 

一 、--__newindex传入的是函数

local mt = {}

mt.__newindex = function (table,key,value)

      print("key值是:",key)

      print("value值是:",value)

end

local t = {aa = "hehe"}

setmetatable(t,mt)

print(t.aa)

--输出表中已有的索引aa 

[LUA-print] hehe    -----  只有一句打印,没有进入元方法中,因为t中有aa索引
 

--为表中不存在的索引进行赋值

t.bb = "wawa"

print(t.bb)

[LUA-print] key值是:   bb
[LUA-print] value值是: wawa

-- 上面两句打印说明进入到了元方法,并且打印了索引 和值

[LUA-print] nil    -- 这句打印非常重要,可以发现t.bb还是空值,说明上面的赋值操作并没有起作用,因为只是进入了元表中,但元表没有进行赋值,所以打印还是nil

--打印完整的t

printt(t)

[LUA-print] ["aa"] = "hehe",  -- 从这个打印可以看出,t 现在还是只有一个索引,并没有赋值成功。

二、--__newindex传入的是table

local mt = {}

local mtTable = {}

mt.__newindex = mtTable

local t = {}

setmetatable(t,mt)

print(t.newkey,mt.newkey)

[LUA-print] nil nil

因为两个t都是空 所以打印都是nil

-- 这里给 t 添加索引并赋值

t.newkey = "this is new value"

print(t.newkey,mtTable.newkey)

[LUA-print] nil   this is new value 

但是打印的结果是 t 并没有赋值成功  反而是mtTable赋值成功。

这是因为给 table 不存在的索引赋值时,进入了他的 元方法,而在元方法中的table 就有了这个键值对。(如果没有设置元表则会直接赋值)

而原先的 t 则 不会受影响。

 

注意 :要避开元方法 避免在取值 和赋值时触发 __index 和__newindex 可以使用  rawget (table,key)  得到指定的索引值 。 以及 rawset(table,key),给指定索引赋值

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值