table.insert 不会触发 __index?

table.insert doesn't trigger __index?

我使用 metatables 做了一个自定义 table,它会在添加元素时自动跟踪尺寸。它运行良好,不再需要 # 运算符或 getn 函数。

但是它有一个问题。如果您调用 table.insert,该函数显然不会调用 __index__newindex。因此,我的 table 无法知道何时以这种方式删除元素。我认为 table.remove 也有同样的问题。

我怎样才能:

谢谢

function Table_new()
    local public = { }
    local tbl = { }
    local size = 0

    function public.size()
        return size
    end

    return setmetatable(public, {
        __newindex = function(t, k, v)
            local previous_v = tbl[k]
            rawset(tbl, k, v)

            if previous_v ~= nil then
                if v == nil then
                    size = size - 1
                end
            elseif v ~= nil then
                size = size + 1
            end
        end,

        __index = tbl
    })
end

local t = Table_new()
t[5] = "hi"
t[17] = "hello"
t[2] = "yo"
t[17]  = nil
print(t.size()) -- prints 2

local z = Table_new()
table.insert(z, "hey")
table.insert(z, "hello")
table.insert(z, "yo")
print(z.size()) -- prints 1 -- why?

如果你在 __newindex 中打印 k,v,你会看到 k 总是 1。这是因为 table.insert 要求 table 的大小来找到插入值。默认情况下,它在最后。您应该添加一个 __len 元方法。但这也许违背了你的目的(这对我来说是模糊的)。