Lua只读表

利用Lua的元表(metatable)和元函数(metafunction)可以很简单的实现此功能。


 

其实现大致分为三个部分

  • 1.禁止在表中创建新值
  • 2.禁止改变已有的值
  • 3.将子表也变为只读

1.禁止在表中创建新值

使用__newindex元函数即可,它的作用就是在表赋新值时调用

local static = {
    exist={exist={exist=true}},
}
setmetatable(static, {__newindex = function() assert(false, 'table is readonly\n') end})
static['not-exist'] = false

这样给只读表赋一个新值,就会报错了

 

2.禁止改变已有的值

这一项功能没有元函数直接提供,可以通过另一个方法巧妙的实现

原理:将传入的表作为返回表的元表__index,这样如果你想要改变值,就会转化为赋新值,这样就会调用元表的__newindex

local readonly = function(t)
    local meta = {
        __index    = t,
        __newindex = function() assert(false, 'table is readonly\n') end,
    }
    local locked = {}
    setmetatable(locked, meta)
    return locked
end


local static = {
    exist={exist={exist=true}},
}
static = readonly(static)
static['exist'] = false

  

3.将子表也变为只读

此功能使用递归很好实现,只要对子表递归调用readonly函数即可。

local static = {
    exist={exist={exist=true}},
}

local readonly
readonly = function(t, deep)
    if deep then
        for k,v in pairs(t) do
            if type(v) == 'table' then
                t[k] = readonly(v, deep)
            end
        end
    end

    local meta = {
        __index    = t,
        __newindex = function() assert(false, 'table is readonly\n') end,
    }
    local locked = {}
    setmetatable(locked, meta)
    return locked
end

static = readonly(static, true)
static['exist']['exist']['exist'] = false

-- 打印表结构,如下图
print(inspect(static))

 

 

至此,readonly表就大成了,虽然其改变了表结果不过表用起来没什么变化

当前,它也存在问题,就是打印表不方便,很不直观,对调试可能会存在影响。

下面是使用inspect打印的表,看这样的表找字段数据,会有股蛋蛋的忧伤。。。

 

转载于:https://www.cnblogs.com/luweimy/p/4450276.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值