以值比對 |
|
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")