Oop 确保表是类的对象?
我制作了一个类Oop 确保表是类的对象?,oop,lua,Oop,Lua,我制作了一个类Apple Apple.lua function apple_new() local self = { } local size = 1 function self.grow() size = size + 1 end function self.size() return size end return self end 如果参数table最初是由函数apple\u new创建的
Apple
Apple.lua
function apple_new()
local self = { }
local size = 1
function self.grow()
size = size + 1
end
function self.size()
return size
end
return self
end
如果参数table
最初是由函数apple\u new
创建的,我想定义一个函数(table)
,它返回true
。我目前还没有找到一种方法来确保“假苹果”不能在该函数中返回true
AppleTest.lua
function is_apple(table)
if type(table) ~= "table" then return false end
return table.grow ~= nil and table.size ~= nil
end
local x = apple_new()
local y = { size = function() end, grow = function() end }
is_apple(x) -- true
is_apple(y) -- true, but it's a fake apple
我相信一个解决方案存在于元表中,它利用了\uuu元表
元方法。但是,如果可能的话,我更喜欢没有它们的解决方案。这相当困难,因为表中的任何变量都可以复制
如何做到这一点?在
Apple.lua
中,添加以下内容
local Apples = { }
setmetatable(Apples, {__mode = "k"})
function apple_new()
local self = { }
Apples[self] = true
...
return self
end
function is_apple(table)
return Apples[table] == true
end
要允许对苹果进行垃圾收集,您需要将
apples
设置为弱表。如果您想实现继承和类函数,也可以按照中的方式来实现
现在,您为Apple定义的任何函数都将可用于使用Apple:new函数创建的任何对象。创建时,所有Apple都将自动成为Apple表的一部分。我不知道弱表是可能的。谢谢@lhf-OP的函数
is_apple
和apple\u new
在不同的文件中定义。如果是这样的话:localy={size=function()end,grow=function()end}Apples[y]=true
我在那篇文章中使用了。它看起来更漂亮,执行速度更快,但只会损失一点内存。它还绕过了:
语法。我不太喜欢使用元表作为类的证明,因为getmetatable
方法如果用户有权访问它,就会造成严重破坏。您可以通过\uuu metaletable
隐藏元表,但这样会阻止以后扩展类。如果使用setmetatable方法,您可以将对象实例上的构造函数与类对象进行比较:local a=Apple:new({foo='bar;})local isAnApple=(a.new=Apple.new)--true
Apple = {}
Apples = {}
function Apple:new (initTable)
local a = initTable or {}
table.insert (Apples, a)
setmetatable (a, self)
self.__index = self
return a
end