Lua中的只写表?

5

我希望在 Lua(特别是 LuaJIT 2.0.3)中有一个只读表,以便:

local tbl = write_once_tbl()
tbl["a"] = 'foo'
tbl["b"] = 'bar'
tbl["a"] = 'baz'  -- asserts false

理想情况下,这应该像普通表格一样运行(pairs()和ipairs()可用)。
__newindex基本上与我希望实现的相反,我不知道如何使用代理表模式使pairs()和ipairs()正常工作。
1个回答

6
你需要使用代理表,也就是一个空表,用于捕获对实际表的所有访问:
function write_once_tbl()
    local T={}
    return setmetatable({},{
        __index=T,
        __newindex=
            function (t,k,v)
                if T[k]==nil then
                    T[k]=v
                else
                    error("table is write-once")
                end
            end,
        __pairs=  function (t) return  pairs(T) end,
        __ipairs= function (t) return ipairs(T) end,
        })
end

请注意,仅从Lua 5.2版本开始,__pairs__ipairs才能正常工作。

我知道代理表,但它们与pairs()或ipairs()不兼容。我刚试了你的代码片段并验证了pairs()和ipairs()不能与之一起使用。 - MikeMx7f
@MikeMx7f,在Lua 5.2和5.3版本中是可以实现的。 - lhf
我在 https://www.lua.org/cgi-bin/demo 上测试了你的代码片段,该网站使用的是 Lua 5.3。 - MikeMx7f
@MikeMx7f,你需要设置__pairs__ipairs元方法。 - lhf
谢谢。你能把它编辑到答案中吗,这样我就可以接受它了(因为问题指定了pairs()和ipairs()的工作方式)。干杯。 - MikeMx7f

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接