调试一个意外的元表脚本中的 null 值

我一直在玩这个元表,但是这个错误是最难修复的:

local Check = {
    InvitedMembers = {
        John = "Allowed",
        Mary = "Allowed",
        Halley = "Allowed"
    }
}
local Filter = {
    __index = function(t,k)
        for i ,v in pairs(t.InvitedMembers) do
            if i ~= k then
                error("我们没有邀请您")
            elseif i == k then
                return "走这边"
            end
        end
    end
}
local ConnectFilter = setmetatable(Check,Filter)
print(Check.InvitedMembers.Sans)

我试图制作一个过滤器,但是这段代码返回了一个 nil 值。

点赞
用户4984564
用户4984564

你的代码中有两个错误:

你索引了错误的表

你在 Check 上调用了 setmetatable,而不是 Check.InvitedMembers。因此,要修复你的代码,你需要写成:

print(Check.Sans)

然后你会得到一个错误:"你不被我们邀请"

你太早抛出了错误

在你的循环中,你要么执行 return,要么抛出一个错误,所以你永远不会跨越第一次迭代。

如果你想要修复循环,你需要像这样写:

for i ,v in pairs(t.InvitedMembers) do
  if i == k then
    return "This way"
  end
end
error("You're not invited by us")

也就是说,遍历整个列表并在找到名字时立即返回,但直到整个列表完成之前不要报错。

但更好的修复方式是这样的:

local Filter = {
    __index = function(t,k)
      if t.InvitedMembers[k] then
        return "This way"
      else
        error("You're not invited by us")
      end
    end
}

由于用一个键索引一个表中没有的值将只返回 nil,所以你可以轻松地找出键是否存在于一个表中。

2020-02-11 13:39:55