关于Lua只读表使用next判空问题

最近在项目中遇到框架上设计的lua只读表,在使用next对表判空时出现一直为nil的情况,后来研究了下只读表的生成,特此记录。

-- lua只读表的生成代码
XReadOnlyTable.Create = function(t)
    for x, y in pairs(t) do
        if type(x) == "table" then
            if type(y) == "table" then
                t[XReadOnlyTable.Create(x)] = XReadOnlyTable.Create(y)
            else
                t[XReadOnlyTable.Create(x)] = y
            end
        elseif type(y) == "table" then
            t[x] = XReadOnlyTable.Create(y)
        end
    end

    local mt = {
        __metatable = "readonly table",
        __index = t,
        __newindex = function()
            XLog.Error("attempt to update a readonly table")
        end,
        __len = function()
            return #t
        end,
        __pairs = function()
            local function stateless_iter(tbl, k)
                local nk, nv = next(tbl, k)
                if nk then return nk, nv end
            end
            return stateless_iter, t, nil
        end
    }

    return setmetatable({}, mt) -- 返回一个空表
end
-- 测试代码
function Test()
    local tableA = {1,2,3,4,5,6,7,8,9}
    local tableB = XReadOnlyTable.Create(tableA)
    XLog.Debug(next(tableB))
    XLog.Debug(tableA[1])
end
	-- 打印
	nil
	1

代码中可以看出,生成只读表的时候返回了一个空表,也就是说tableB是个带有自己设定好特殊原表的空表,在使用next调用tableB的时候,也是调用的这个空表,所以返回的是nil。
而按照索引对表进行访问的时候,由于访问空表找不到元素值,就去访问原表,找到了带有数据的tableA,返回指定索引数据。
在日后对表判空还是建议使用next,对于项目内自定义的只读表还要多加注意。

菜鸟一枚,欢迎指正。

你可能感兴趣的:(Lua)