• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

Lua只读表

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

利用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打印的表,看这样的表找字段数据,会有股蛋蛋的忧伤。。。

 


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
lua下的简单OO实现发布时间:2022-07-22
下一篇:
luamath库发布时间:2022-07-22
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap