简单的元组

lua-users home
wiki

一个非常简单的内部化不可变二元组实现。元组成员不能是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

另请参阅


RecentChanges · preferences
编辑 · 历史
最后编辑于2007年8月2日晚上11:08 GMT (差异)