簡易 Tuple

lua-users home
維基

一個非常簡單的內部化不可變 2-tuple 實作。Tuple 成員不能是 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 行是可選的;在實務中,我會將它與不會長期存在的 tuple 快取一起使用,並且丟棄整個快取會更容易。

用法:將以上程式碼放入一個檔案中,例如 TupleCache.lua。建立一個 tuple 函式

local FooTuple = require"TupleCache"()

然後您可以使用 tuple 函式建立新的 FooTuples

local t = FooTuple(obja, objb)

FooTuple 函式本身擁有對快取表的唯一參考,因此一旦 FooTuple 不再有參考,快取表就會被垃圾回收。但是,tuple 本身將繼續存在;您只是無法建立新的 tuple。

要提取 tuple 的值,請呼叫它

local obja, objb = t()

如果您真的需要能夠包含 nilNaN 的 tuple,您可以使用此版本

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 (差異)