當你創建一個表,只需在假添加一個空表,並設置它的元表:
local fake = {}
do
local lookup = {} --Will be using this to avoid using lots of metatables
local real = {}
local meta
meta = {
__index = function(self,i)
return rawget(lookup[self], i)
end,
__newindex = function(self,i,v)
rawset(lookup[self], i, v)
if type(v) == "table" then
rawset(self, i, setmetatable({},meta))
lookup[self[i]] = v
end
end
}
setmetatable(fake, meta)
lookup[fake] = real
end
fake[1] = "hello"
print(fake[1])
print(rawget(fake, 1))
fake.x = {"hi"}
print(fake.x)
print(rawget(fake, 'x')) --This still prints a table because there actually is one, but in reality it's abiding by our rules
print(fake.x[1])
print(rawget(fake.x, 1))
fake.x.y = "aha"
print(fake.x.y)
print(rawget(fake.x, 'y'))
用這種方法唯一需要注意的是,他們可以直接修改數據庫,像這樣:
fake.myvalue = {}
fake.myvalue = 5
另一種方法可能是包,你去:
local fake = {}
do
local lookup = {} --Will be using this to avoid using lots of metatables
local cache = {} --will be using to avoid usings tons of new objects
local real = {}
local meta
meta = {
__index = function(self,i)
local val = rawget(lookup[self], i)
if type(val) == "table" then
if cache[val] then
return cache[val]
else
local faker = {}
lookup[faker] = val
cache[val] = faker
return setmetatable(faker, meta)
end
else
return val
end
end,
__newindex = function(self,i,v)
rawset(lookup[self], i, v)
end
}
setmetatable(fake, meta)
lookup[fake] = real
end
fake[1] = "hello"
print(fake[1])
print(rawget(fake, 1))
fake.x = {"hi"}
print(fake.x)
print(rawget(fake, 'x')) --This still prints a table because there actually is one, but in reality it's abiding by our rules
print(fake.x[1])
print(rawget(fake.x, 1))
fake.x.y = "aha"
print(fake.x.y)
print(rawget(fake.x, 'y'))
完全避免了直接修改問題