Lua的__index和__newindex

1.__index

table = {}

newTable = {age = 7}

setmetatable(table, newTable)

print(table.age)

上段代码输出为nil

 

table = {}

newTable = {age = 7}

setmetatable(table, newTable)

newTable.__index = newTable

print(table.age)

改成这样后输出为7

 

table = {age = 6}

newTable = {age = 7}

setmetatable(table, newTable)

newTable.__index = newTable

print(table.age)

这段代码的输出为6

 

table = {}

newTable = { __index = function() print("猜猜我的年龄") end,

age = 7}

setmetatable(table, newTable)

print(table.age)

这样的输出是 "猜猜我的年龄" 和 nil

 

总结Lua查找元素的规则如下: 
①在表中查找,找到则返回,找不到则继续 
②判断是否有元表,没有返回nil,有则继续 
③判断元表有无__index方法,如果该方法为nil,则返回nil;如果是一个表,则重复①②③;如果是一个函数,则返回函数的返回值

 

2.__newindex,当一个表里找不到索引赋值时,就会去找__newindex元方法,如果是个表,机会进行赋值,如果是个函数,就会执行函数而不赋值,于是可以实现只读的table,举例:

function readOnly(t)
     local proxy = {}

     local mt = {
          __index = t,
     }

     setmetatable(proxy, mt)
     return proxy
end

local tbDemo = readOnly{1, 2, 3, 4, 5}
print(tbDemo[1])
tbDemo[1] = 20
print(tbDemo[1])

上面这段代码的输出是1和20。

function readOnly(t)
     local proxy = {}
    
     local mt = {
          __index = t,
          __newindex = function (t, k, v)
               error("Attempt to update a read-only table", 2)
          end
     }

     setmetatable(proxy, mt)
     return proxy
end

local tbDemo = readOnly{1, 2, 3, 4, 5}
print(tbDemo[1])
tbDemo[1] = 20
print(tbDemo[1])

上面这段代码的输出是1和"Attempt to update a read-only table"的报错

 

local t = {1, 2, 3, 4, 5}
local mt = {
    __index = mt,
    __newindex = function(t, k, v)
        print(t)
        print(k)
        print(v)
    end
}
setmetatable(t, mt)
t[1] = 20
print(t[1])

上段代码输出为20

 

local t = {}
local mt = {
    __index = mt,
    __newindex = function(t, k, v)
        print(t)
        print(k)
        print(v)
    end
}
setmetatable(t, mt)
t[1] = 20
print(t[1])

上段代码的输出为

table: 0x563368ac81f0
1
20
nil

转载于:https://my.oschina.net/u/3860932/blog/3099011

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值