对于深层嵌套表中的字段,例如text.title.1.font。即使你使用
if text.title.1.font then ... end
它会导致类似&#34的错误;尝试索引全局'文本' (零值)"如果表的任何级别实际上不存在。当然,人们可能会试图检查表中每个级别的存在,但这看起来相当麻烦。我想知道是否有一种更安全,更漂亮的方法来处理这个问题,这样当引用这样的对象时,nil会是值而不是触发错误?
答案 0 :(得分:1)
Egor的建议debug.setmetatable(nil, {__index = function()end})
是最容易申请的。请记住,它不是词法范围的,因此,一旦打开,它将“打开”直到关闭,这可能会在代码的其他部分产生意想不到的后果。有关讨论和一些备选方案,请参阅this thread。
另请注意,text.title.1.font
应该是text.title[1].font
或text.title['1'].font
(这两个不一样)。
另一个,更冗长,但仍然可用的替代方案是:
if (((text or {}).title or {})[1] or {}).font then ... end
答案 1 :(得分:1)
这样做不会引起大量错误的方法是明确告诉Lua默认情况下哪些表应该是表的哪些字段。你可以用metatables做到这一点。以下是一个示例,但它应该根据您希望表格的结构进行自定义。
-- This metatable is intended to catch bugs by keeping default tables empty.
local default_mt = {
__newindex =
function()
error(
'This is a default table. You have to make nested tables the old-fashioned way.')
end
}
local number_mt = {
__index =
function(self, key)
if type(key) == 'number' then
return setmetatable({}, default_mt)
end
end
}
local default_number_mt = {
__index = number_mt.__index,
__newindex = default_mt.__newindex
}
local title_mt = {__index = {title = setmetatable({}, default_number_mt)}}
local text = setmetatable({}, title_mt)
print(text.title[1].font)