简单元组 |
|
nil
或 NaN
-- 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()
如果你真的需要能够包含 nil
和 NaN
的元组,你可以使用此版本
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