对Lua中__index和__newindex的基础理解


table对于元素的操作有 查询 和 赋值 两种。
__index和__newindex都是元方法,存在于元表中
这两种方法都不一定是一个table,也有可能是一个函数

__index 主要用于对table的查询

__index 主要用于对table的查询:
如果子表中的元素不存在,lua就会调用元表中的__index,去元表中查找对应的元素。
这里的元素并不局限于字段,也包括方法和table。

__index 例子:

local tableChild = {
    age = "25",
}
local tableParent = {
    __index = {
        name = "憨憨的小韩",
        age = "20"
    },
}
setmetatable(tableChild, tableParent)
--子表中没有name,就去它元表中的index里面找name这个字段
print("子表name:" .. tostring(tableChild.name))
--子表已经有了age,直接输入value
print("子表age:" .. tostring(tableChild.age))
输入结果:
子表name:憨憨的小韩
子表age: 25

__newindex 主要用于对table的赋值更新

__newindex主要用于对table的赋值更新
如果想对子表中不存在的索引赋值时,lua就会调用元表中的__newindex元方法,
如果该方法是一个函数,就会执行这个方法

举个例子:

local tableChild = {
    age = "25"
}
local newIndexTable = {}
local tableParent = {
    __newindex = function (table, key, value)
        print("想要访问 " .. key .. " 但子表中没有")
    end,
}
setmetatable(tableChild, tableParent)
print("子表name:" .. tostring(tableChild.name))
tableChild.name = "憨憨的小韩"
print("子表name:" .. tostring(tableChild.name))
输入结果:
子表name:nil
想要访问 name 但子表中没有
子表name:nil

可以看出,当有__newindex的时候,给子表中不存在的元素赋值时,会执行__newindex指向的function,并且该操作并不会给子表新添加一个元素。

如果__newindex是一个table,lua就在这个table中进行赋值,而不对子表进行中的元素进行操作

举个例子:

local tableChild = {
    age = "25"
}
local newIndexTable = {}
local tableParent = {

    __newindex = newIndexTable
}
setmetatable(tableChild, tableParent)
print("子表name:" .. tostring(tableChild.name))
print("newIndexTablename:" .. tostring(newIndexTable.name))
tableChild.name = "憨憨的小韩"
print("子表name:" .. tostring(tableChild.name))
print("newIndexTablename:" .. tostring(newIndexTable.name))
输出结果:
子表name:nil
newIndexTablename:nil
子表name:nil
newIndexTablename:憨憨的小韩

上面这个例子可以看出,我们把newIndexTable这个table当做元表中的__newindex时,给子表中的name赋值,这个name并没有赋到子表当中,而会赋到了newIndexTable这个表中。

rawset

如果我们想通过__newindex去更新子表中元素的值的时候,我们需要使用rawset这个方法。
该方法最最最重要的功能就是使元方法失效。

还是以__newindex为函数的那个例子基础

   local tableChild = {
        age = "25"
    }
    local tableParent = {
        __newindex = function (table, key, value)
            print("给子表中的 " .. key .. " 赋值 " .. value)
            rawset(table,key,value)
        end,
    }
    setmetatable(tableChild, tableParent)
    print("子表name:" .. tostring(tableChild.name))
    tableChild.name = "憨憨的小韩"
    print("子表name:" .. tostring(tableChild.name))
输出结果:
子表name:nil
给子表中的 name 赋值 憨憨的小韩
子表name:憨憨的小韩

以上本文总结的__index和__newindex的基础用法。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值