4

Lua 中是否有类似于collections.defaultdictPython 中可用的功能,它自动处理不存在的关联数组键的默认值?

我希望下面的代码设置nilv而不是错误。所以基本上是一种a[2](不存在的键)table默认情况下的方法:

a = {}
v = a[2][3] 

>>> PANIC: unprotected error in call to Lua API (main.lua:603: attempt to index field '?' (a nil value))

在 Python 中可以这样完成:

>>> import collections
>>> a = collections.defaultdict(dict)
>>> print a[2]
{}
4

2 回答 2

5

是否有 Lua 标准功能可以做到这一点?不,但是您可以使用元表轻松做到这一点。你甚至可以编写一个函数来创建这样的表:

function CreateTableWithDefaultElement(default)
  local tbl = {}
  local mtbl = {}
  mtbl.__index = function(tbl, key)
    local val = rawget(tbl, key)
    return val or default
  end
  setmetatable(tbl, mtbl)
  return tbl
end

请注意,每个元素都将获得相同的默认值。因此,如果您将默认值设为表,则返回表中的每个“空”元素将有效地引用同一个表。如果这不是您想要的,则必须修改该功能。

于 2012-04-29T10:02:46.733 回答
2

只是想我会分享我的这段代码版本,如果有人发现它需要一个与表、对象等兼容的版本。此外,与 Nicol 的解决方案相反,这实际上在表中创建了请求的条目。

function defaultdict(default_value_factory)
    local t = {}
    local metatable = {}
    metatable.__index = function(t, key)
        if not rawget(t, key) then
            rawset(t, key, default_value_factory(key))
        end
        return rawget(t, key)
    end
    return setmetatable(t, metatable)
end

示例用法:

d = defaultidct(function() return {} end)
table.insert(d["people"], {"Bob", "The Builder"})

names = defaultdict(function(key) return key end)
print(names["bob"]) -- bob
names["bob"] = "bob the builder"
names["ashley"] = "ashley the fire princess"
于 2014-09-05T22:26:38.613 回答