只读 lua 中的可迭代 table?
Read only iterable table in lua?
我想在我的 Lua 程序中有一个只读的 table。如果某个键被删除或某个键与新值相关联,则必须抛出错误。
function readonly(table)
local meta = { } -- metatable for proxy
local proxy = { } -- this table is always empty
meta.__index = table -- refer to table for lookups
meta.__newindex = function(t, key, value)
error("You cannot make any changes to this table!")
end
setmetatable(proxy, meta)
return proxy -- user will use proxy instead
end
效果很好。
t = { }
t["Apple"] = "Red"
t[true] = "True!"
t[51] = 29
for k,v in pairs(t) do
print(v)
end
t = readonly(t)
t[51] = 30
版画
Red
True!
29
input:7: You cannot make any changes to this table!
问题
for k, v in pairs(t) do
print(v)
end
现在在任何情况下都不会打印任何内容。那是因为 proxy
table 里面永远不会有任何东西。 pairs
显然从不调用 index
因此无法从实际的 table.
中检索任何内容
我该怎么做才能使这个只读 table 可迭代?
我在 Lua 5.1 上并且可以访问这些元方法:
您可以修改标准 Lua 函数 pairs
以正确处理只读表。
local function readonly_newindex(t, key, value)
error("You cannot make any changes to this table!")
end
function readonly(tbl)
return
setmetatable({}, {
__index = tbl,
__newindex = readonly_newindex
})
end
local original_pairs = pairs
function pairs(tbl)
if next(tbl) == nil then
local mt = getmetatable(tbl)
if mt and mt.__newindex == readonly_newindex then
tbl = mt.__index
end
end
return original_pairs(tbl)
end
用法:
t = { }
t["Apple"] = "Red"
t[true] = "True!"
t[51] = 29
for k,v in pairs(t) do
print(k, v)
end
t = readonly(t)
for k,v in pairs(t) do
print(k, v)
end
t[51] = 30
一个解决方案是为 table.
创建一个完全自定义的迭代器
function readonly(table)
local meta = { } -- metatable for proxy
local proxy = { } -- this table is always empty
meta.__index = table -- refer to table for lookups
meta.__newindex = function(t, key, value)
error("You cannot make any changes to this table!")
end
local function iter()
return next, table
end
setmetatable(proxy, meta)
return proxy, iter -- user will use proxy instead
end
用法:
t = { }
t["Apple"] = "Red"
t[true] = "True!"
t[51] = 29
for k,v in pairs(t) do
print(v)
end
t, tIter = readonly(t)
t[51] = 30
for k, v in tIter do
print(v)
end
我想在我的 Lua 程序中有一个只读的 table。如果某个键被删除或某个键与新值相关联,则必须抛出错误。
function readonly(table)
local meta = { } -- metatable for proxy
local proxy = { } -- this table is always empty
meta.__index = table -- refer to table for lookups
meta.__newindex = function(t, key, value)
error("You cannot make any changes to this table!")
end
setmetatable(proxy, meta)
return proxy -- user will use proxy instead
end
效果很好。
t = { }
t["Apple"] = "Red"
t[true] = "True!"
t[51] = 29
for k,v in pairs(t) do
print(v)
end
t = readonly(t)
t[51] = 30
版画
Red
True!
29
input:7: You cannot make any changes to this table!
问题
for k, v in pairs(t) do
print(v)
end
现在在任何情况下都不会打印任何内容。那是因为 proxy
table 里面永远不会有任何东西。 pairs
显然从不调用 index
因此无法从实际的 table.
我该怎么做才能使这个只读 table 可迭代?
我在 Lua 5.1 上并且可以访问这些元方法:
您可以修改标准 Lua 函数 pairs
以正确处理只读表。
local function readonly_newindex(t, key, value)
error("You cannot make any changes to this table!")
end
function readonly(tbl)
return
setmetatable({}, {
__index = tbl,
__newindex = readonly_newindex
})
end
local original_pairs = pairs
function pairs(tbl)
if next(tbl) == nil then
local mt = getmetatable(tbl)
if mt and mt.__newindex == readonly_newindex then
tbl = mt.__index
end
end
return original_pairs(tbl)
end
用法:
t = { }
t["Apple"] = "Red"
t[true] = "True!"
t[51] = 29
for k,v in pairs(t) do
print(k, v)
end
t = readonly(t)
for k,v in pairs(t) do
print(k, v)
end
t[51] = 30
一个解决方案是为 table.
创建一个完全自定义的迭代器function readonly(table)
local meta = { } -- metatable for proxy
local proxy = { } -- this table is always empty
meta.__index = table -- refer to table for lookups
meta.__newindex = function(t, key, value)
error("You cannot make any changes to this table!")
end
local function iter()
return next, table
end
setmetatable(proxy, meta)
return proxy, iter -- user will use proxy instead
end
用法:
t = { }
t["Apple"] = "Red"
t[true] = "True!"
t[51] = 29
for k,v in pairs(t) do
print(v)
end
t, tIter = readonly(t)
t[51] = 30
for k, v in tIter do
print(v)
end