按值比较 |
|
hashed
函数为给定的表 t
添加了一个元表,因此表中的任何写入或读取操作实际上都会使用键的哈希值而不是键本身。这允许模拟按值比较键。为了实现这一点,请确保应该具有相同值的两个对象(表或用户数据)具有相同的哈希值。
local function gethash(k) local hash = k local mt = getmetatable(k) local __hash = mt and mt.__hash if type(__hash)=='function' then hash = __hash(k) elseif type(__hash)~='nil' then hash = __hash end return hash end function hashed(t) return setmetatable(t, { __index = function(t, k) return t[gethash(k)] end, __newindex = function(t, k, v) rawset(t, gethash(k), v) end, }) end -- example usage local t1 = setmetatable({}, {__hash = 42}) local t2 = setmetatable({}, {__hash = 42}) local t = {} t[t1] = "foo" assert(t[t2]==nil) t = hashed({}) t[t1] = "foo" assert(t[t2]=="foo") t[t2] = "bar" assert(t[t1]=="bar")
local mt = { __mode = 'kv', __index = function(t,k) return k end } local function newkeymap(t) return setmetatable(t or {}, mt) end function hashed(t, keymap) return setmetatable(t, { __index = function(t, k) return rawget(t, keymap[k]) end, __newindex = function(t, k, v) rawset(t, keymap[k], v) end, }) end -- example usage local t = {} t.BAR = "foo" assert(t.bar==nil) local keymap = newkeymap { BAR = 'bar' } t = hashed({}, keymap) t.bar = "foo" assert(t.BAR=="foo") t.BAR = "bar" assert(t.bar=="bar")