简单元组

lua-users home
wiki

一个非常简单的内部不可变 2 元组实现。元组成员不能是 nilNaN

-- An interned 2-tuple type, in pure Lua.
--
do
  -- The constructor makes a tuple function, which has its own
  -- intern table.
        
  local setmetatable = setmetatable

  local function tmaker(a)
    return {__index = function(t, b)
                        local function tuple() return a, b end
                        t[b] = tuple
                        return tuple
                      end,
            __mode = "kv"
           }
  end 
  local meta = {
      __index = function(t, a)
                  local v = setmetatable({}, tmaker(a))
                  t[a] = v
                  return v
                end,
      __mode = "k"
  } 
  return function()
    local intern = setmetatable({}, meta)
    return function(a, b)
      return intern[a][b]
    end
  end
end

__mode 行是可选的;在实践中,我将它与非长生命周期的元组缓存一起使用,并且丢弃整个缓存更容易。

用法:将上述内容放在一个名为 TupleCache.lua 的文件中。创建一个元组函数

local FooTuple = require"TupleCache"()

然后你可以使用元组函数创建新的 FooTuples

local t = FooTuple(obja, objb)

FooTuple 函数本身对缓存表具有唯一的引用,因此一旦 FooTuple 不再具有引用,缓存表将被垃圾回收。但是,元组本身将继续存在;你只是不能创建新的元组。

要提取元组的值,请调用它

local obja, objb = t()

如果你真的需要能够包含 nilNaN 的元组,你可以使用此版本

do
  -- The constructor makes a tuple function, which has its own
  -- intern table.

  local rawget, setmetatable = rawget, setmetatable
  local NIL, NAN = {}, {}
  
  local function check(t, a)
    if a == a and a ~= nil then return a end
    local fixa = a and NAN or NIL
    return fixa, rawget(t, fixa)
  end

  local function tmaker(a)
    return {__index = function(t, b)
                        local fixb, tuple = check(t, b)
                        tuple = tuple or function() return a, b end
                        t[fixb] = tuple
                        return tuple
                      end
           }
  end
  local meta = {
      __index = function(t, a)
                  local fixa, v = check(t, a)
                  v = v or setmetatable({}, tmaker(a))
                  t[fixa] = v
                  return v
                end
  }
  return function()
    local intern = setmetatable({}, meta)
    return function(a, b)
      return intern[a][b]
    end
  end
end

另请参阅


最近更改 · 偏好设置
编辑 · 历史记录
最后编辑于 2007 年 8 月 3 日凌晨 5:08 GMT (差异)