Oop 在Lua中的新对象上指定元表
方法/1Oop 在Lua中的新对象上指定元表,oop,lua,lua-table,metatable,Oop,Lua,Lua Table,Metatable,方法/1 Dog = {} function Dog:new() local newObj = {sound = 'woof'} return setmetatable(newObj, { __index = self }) end 方法/2 Dog = {} function Dog:new() local newObj = {sound = 'woof'} self.__index = self return setmetatable(newObj, self) e
Dog = {}
function Dog:new()
local newObj = {sound = 'woof'}
return setmetatable(newObj, { __index = self })
end
方法/2
Dog = {}
function Dog:new()
local newObj = {sound = 'woof'}
self.__index = self
return setmetatable(newObj, self)
end
大多数时候,我都看到人们使用self.\uu index=self方法,这在我看来很笨拙。为什么要将整个Dog
对象以及所有不构成元表的附加方法传递给setmetatable
Method/1有助于设置新对象的元表。对于Dog
对象,索引也更干净
是否有充分的理由使用方法/2而不是方法/1?
一些额外的代码来提供上下文,这两种方法都可以使用
function Dog:makeSound()
print('I say ' .. self.sound)
end
mrDog = Dog:new()
mrDog:makeSound()
方法/2比方法/1更优化,因为它不需要创建额外的表作为其元表。它将自身用作元表
既然您说您认为方法/1在您的问题中更为清晰,请随意使用它。我认为在大多数情况下,两者之间的性能差异并不重要。可读性几乎总是更为重要。虽然两种方法都实现了相同的最终行为,但有人可能更喜欢方法2,因为它更符合“回收资源优于创建”的政策。方法2将始终使用一个表Dog
作为元表,而不管您创建了多少个Dog对象。方法1,OTOH,将创建一个新的匿名表,作为每个Dog对象的元
然而,对于语言的新手来说,方法1可能更容易阅读和理解,因为它不会将元表和对象定义的关注点混合在一起。如果你想要一个\ueq
元方法,你必须在所有实例之间共享一个元表,否则它将无法工作。在这种情况下,您的方法1将不起作用
但是元表不需要是Dog
,它可以是专用元表:
方法3。
方法/2
如果只定义函数狗:\uuu eq(rhs)
,则可以正常工作。此方法允许您以相同的方式定义元方法和非元方法。正因为如此,我更喜欢这种方法。@moteus你是对的,但我认为finnw想说的是,比较“类型”相等性的常用方法是检查该对象的元表。如果每个对象都有不同的机器翻译,这种方法就不起作用。不幸的是,他的例子并没有强调这一点。
Dog = {}
local DogMeta = {__index = Dog}
function Dog:new(name)
local newObj = {sound = 'woof', name = name}
return setmetatable(newObj, DogMeta)
end
function DogMeta.__eq(dog1, dog2)
return dog1.name == dog2.name
end