zoukankan      html  css  js  c++  java
  • Lua只读表

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


    其实现大致分为三个部分

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

  • 相关阅读:
    nyoj 202红黑树 (搜索)
    POJ 3281 Dining(最大流)
    nyoj-488 素数环 +nyoj -32 组合数 (搜索)
    LeetCode100:Same Tree
    LeetCode283:Move Zeros
    Leetcode226:Invert Binary Tree
    LeetCode258:Add Digits
    Leetcode237:Delete Node in a Linked List
    LeetCode7:Reverse Integer
    LeetCode292:Nim Game
  • 原文地址:https://www.cnblogs.com/luweimy/p/4450276.html
Copyright © 2011-2022 走看看