我对Lua中的物体知之甚少,所以请耐心等待 示例代码:
Colors = {
primary = "BF2626",
primaryGradient = {"CC2929", "B32424"}
}
function Colors:new(o)
o = o or {}
setmetatable(o, self)
self.__index = self
return o
end
function Colors:setPrimaryGradient()
self.primaryGradient[1] ="Changed"
end
function Colors:setPrimary()
self.primary ="00FF00"
end
a =Colors:new()
b =Colors:new()
b:setPrimaryGradient()
b:setPrimary()
print(a.primaryGradient[1])
print(b.primaryGradient[1])
print(a.primary)
print(b.primary)
输出:
Changed
Changed
BF2626
00FF00
我做错了什么?
为什么变量 primary 为每个对象保留其值,但表没有?
感谢。
答案 0 :(得分:3)
您的new
函数为空表设置元表。此metatable具有和函数的内部数据。它还设置了__index
元方法。这很重要。
您的setPrimaryGradient
方法将self
作为隐式参数。在这种情况下,self
是在new
中创建的新表。你的问题在这里:
self.primaryGradient[1]
不是一个单独的构造。它是两个独立的操作。让我们写出Lua如何使用它:self["primaryGradient"][1]
。看到问题了?
第一部分self["primaryGradient"]
将检查self
表并获取primaryGradient
成员。问题是因为self
有一个__index
元方法,并且primaryGradient
中没有self
成员,因此它会直接使用__index
元方法。因此它将从metatable 获取primaryGradient
。一个共享的元表。
然后将在metatable的成员上执行[1]
部分,并且值将存储在metatable 的primaryGradient
的第一个元素中。
setPrimary
没有出现同样问题的原因很简单。 self.primary
是一项操作。因为它是一个表访问,后跟一个赋值操作,所以Lua不会使用__index
元方法。它将改为使用__newindex
元方法。由于您没有为self
的metatable定义一个,它将使用默认逻辑:在self
中创建一个新成员并设置其值。
setPrimaryGradient
不使用__newindex
的原因是因为它。只是不能访问self
。它使用__newindex
访问self["primaryGradient"]
;只有 last 表访问才能获得__newindex
电话。
如果要使用可以修改的某些默认值初始化类型,则需要复制这些值。你有时不能只参考全球的。嗯,你可以,但设置起来会很痛苦。
答案 1 :(得分:1)
可以通过这种方式轻松解决问题:
Colors = {
primary = "BF2626",
primaryGradient = {"CC2929", "B32424"}
}
Colors.primaryGradient.__index = Colors.primaryGradient
function Colors:new(o)
o = o or {primaryGradient = setmetatable({}, self.primaryGradient)}
setmetatable(o, self)
self.__index = self
return o
end