lua中__index、__newindex元方法

借鉴自:https://www.kancloud.cn/digest/luanote/119936
https://blog.csdn.net/xocoder/article/details/9028347
https://www.jb51.net/article/55155.htm

__index元方法(索引查询):

默认情况下,当我们访问一个table中不存在的字段时,得到的结果时nil,但是这种状况很容易被改变,lua是按照以下步骤决定是返回nil还是其他值的:

1.当访问一个table的字段时,如果table有这个字段,则直接访问对应的值
2.当table没有这个字段,判断该table是否有元表,如果没有元表,则返回nil有元表则继续
3.判断元表中有没有__index元方法,如果没有(即__index方法为nil),则返回nil,如果__index方法是一个table则重复1、2、3步骤,如果__index方法是一个函数,则这个字段作为该函数的第二个参数,然后返回该函数的返回值

__index元方法定义为函数时有2个参数table本身,字段名   function(table,key)  

 Windows.mt.__index = function (table, key)中的table可以换成t、x等任意的变量,都表示为该表,如果此函数用不到该表,则可以写成Windows.mt.__index = function (_, key),也就是说如果__index赋值成一个元方法,则第一个参数则被默认赋值为该表,类比self的用法,__newindex同样使用

Windows = {} 
 
Windows.default = {x = 0, y = 0, width = 100, height = 100, color = {r = 255, g = 255, b = 255}}

-- 创建元表
Windows.mt = {} 
 
-- 声明构造函数 
function Windows.new(o)
    --将m设置为其元表
     setmetatable(o, Windows.mt)
     return o
end
 
-- 定义__index元方法
Windows.mt.__index = function (table, key)
     return Windows.default[key]
end
 
local win = Windows.new({x = 10, y = 10})
print(win.x)               -- >10 访问自身已经拥有的值
print(win.width)          -- >100 访问default表中的值
print(win.color.r)          -- >255 访问default表中的值

print(win.x)时,由于win变量本身就拥有x字段,所以就直接打印了其自身拥有的字段的值;print(win.width),由于win变量本身没有width字段,那么就去查找是否拥有元表,元表中是否有__index对应的元方法,由于存在__index元方法,返回了default表中的width字段的值,print(win.color.r)也是同样的道理

__newindex元方法(索引更新):

__newindex元方法与__index类似,__newindex用于更新table中的数据,而__index用于查询table中的数据。当对一个table中不存在的索引赋值时(存在索引当然就直接赋值了),在Lua中是按照以下步骤进行的:

1.判断该table是否有元表,如果有了元表,就查找元表中是否有__newindex元方法,如果没有元表,就直接添加这个索引,然后对应的赋值
2.如果有元表中__newindex方法,则去执行该方法,而不去执行赋值
3.如果该__newindex方法是一个table时,就在这个table中执行赋值,而不是原来的table,如果该__newindex方法是一个函数执行该函数

__newindex元方法定义为函数时有3个参数:table本身、字段名、想要被赋予的值 function(table,key,value)

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值