• 【Lua】把一个 table 设为只读的,不允许新增字段或修改字段


    参考帖子:

    https://www.cnblogs.com/luweimy/p/4450276.html

    配置表是肯定不允许在运行时更改的,所以有必要做成【只读】的table。

    功能的实现大致分为三个部分

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

    1.禁止在表中创建新值

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

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

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

    2.禁止改变已有的值

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

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

    local readonly = function(t)
        local meta = {
            __index    = t,
            __newindex = function() assert(false, 'table is readonly
    ') 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
    ') end,
        }
        local locked = {}
        setmetatable(locked, meta)
        return locked
    end
    
    static = readonly(static, true)
    static['exist']['exist']['exist'] = false
    
    -- 打印表结构,如下图
    print(inspect(static))

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

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

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

    00

  • 相关阅读:
    C语言学生管理系统(原版本)(自编)
    【JavaScript】解构赋值
    【JavaScript】箭头函数
    【JavaScript】typeof 和 instanceof
    【JavaScript】Proxy 实例方法(二)
    【JavaScript】Proxy 实例方法(一)
    【JavaScript】Reflect 静态方法(二)
    【JavaScript】Reflect 静态方法(一)
    【JavaScript】async function
    开发系统关键字(例子)
  • 原文地址:https://www.cnblogs.com/rollingyouandme/p/15349979.html
Copyright © 2020-2023  润新知