Lua如何检查一个表是否是“实例”

7

给定一个表格,有没有方法可以检查它是否是任何类的实例对象?

假设所有的类定义都长这样:

Class = {}
Class.__index = Class

function Class.new()
    return setmetatable({}, Class) -- returns an instance
end
2个回答

6
我只使用getmetatable函数。
if getmetatable(thing) == Class then

但如果您使用某种继承,则可以尝试此方法

local A = {} A.__index = A
function A:new() return setmetatable({}, A) end
function A:foo() print('foo') end

local B = setmetatable({}, A) B.__index = B
function B:new() return setmetatable({}, B) end
function B:boo() print("boo") end

local function is_instance(o, class)
  while o do
    o = getmetatable(o)
    if class == o then return true end
  end
  return false
end

local a = A:new()
local b = B:new()

a:foo()
b:foo()
b:boo()

print(is_instance(a, A))
print(is_instance(a, B))
print(is_instance(b, B))
print(is_instance(b, A))

这应该是被接受的答案。 - Yan Kalbaska

3
在理论上,您可以使用getmetatable()读取表的元表,并将接收到的表与您已知的类列表进行比较。
但这意味着元表不应受保护(__metatable字段未设置为其他内容,在沙箱中未删除getmetatable()等),而且您应该了解所有可用的类。
如果在表上设置了一些元表,并不意味着该表是类层次结构的一部分,或者根本是类。它只可能使用元表来解决自己的任务。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接