表map

# 在table的基础上做了轻量级封装,可以获取到元素数量,如果用table,需要每次遍历所有k,v才行

local map = {}
map.__cname = "util.map"

local null = {}
map.null = null

map.__newindex = function(self, k, v)
    error(string.format("use map:Add to add new k-v: %s-%s", k, v))
end
map.__index = map

function map.new()
    local obj = {}
    obj:ctor()
    setmetatable(obj, map)
    return obj
end

function map.attach(tb)
    setmetatable(tb, map)
    local count = 0
    for k, v in pairs(tb) do
        count = count + 1
    end
    tb._count = count
    tb._ver = 0
    return tb
end

function map:ctor()
    self._count = 0
    self._ver = 0
end

function map:Clear()
    if self._count < 1 then return end
    for k, v in pairs(self) do
        self[k] = nil
    end
    self._count = 0
    self:_IcrVersion()
end

function map:_IcrVersion()
    self._ver = self._ver + 1
end

function map:GetCount()
    return self._count
end

function map:Add(k, v)
    local oldV = self[k]
    assert(nil == oldV)

    if nil == v then v = null end
    rawset(self, k, v) --self[k] = v
    self._count = self._count + 1
    self:_IcrVersion()
end

function map:Remove(k)
    local oldV = self[k]
    if nil == oldV then return false, nil end

    self[k] = nil
    self._count = self._count - 1
    self:_IcrVersion()
    return true, oldV
end

function map:Set(k, v)
    local oldV = self[k]
    if nil == oldV then
        self:Add(k, v)
    else
        oldV.value = v
    end
end

function map:Get(k)
    return self[k]
end

function map:ContainsKey(k)
    return nil ~= self[k]
end

function map:__tostring()
    if self._count <= 0 then return "" end

    local strTb = {}
    local count = 0
    for k, v in self do
        if count > 0 then
            table.insert(strTb, ",")
        end
        table.insert(strTb, tostring(k))
        table.insert(strTb, "->")
        if null == v then
            table.insert(strTb, "null")
        else
            table.insert(strTb, tostring(v))
        end
        count = count + 1
    end
    return table.concat(strTb)
end

function map:ipairs()
    error("use map:pairs")
end

function map:pairs()
    local version = self._ver
    local function iterator(tb, k)
        if version ~= self._ver then error("map modified in pairs") end

        local n_k, v = next(self, k)
        return n_k, v
    end
    return iterator
end

function map:IsReadOnly()
    return false
end

return map

 

posted @ 2022-03-20 21:28  yanghui01  阅读(51)  评论(0编辑  收藏  举报