修改对象中表格的值会将所有对象的值都改变。我该如何使它只改变特定对象的值?

我对 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_为每个对象保留其值,但表格却没有呢?

谢谢。

点赞
用户734069
用户734069

你的 new 函数为空表设置了元表。这个元表有函数和内部数据。它还设置了一个 __index 元方法。这很重要。

你的 setPrimaryGradient 方法将 self 作为一个隐含的参数。在这种情况下,self 是在 new 中创建的新表。你的问题在这里:

self.primaryGradient[1] 并不是一个单独的构造。它是 _两个单独的操作_。我们来看看 Lua 如何使用它:self["primaryGradient"][1]。看到问题了吗?

首先,self["primaryGradient"] 将检查 self 表并获取它的 primaryGradient 成员。问题在于,因为 self 有一个 __index 元方法,并且 self 直接没有 primaryGradient 成员,它将直接使用 __index 元方法。因此,它将从元表中获取 primaryGradient。这是一个_共享_的元表。

然后,[1] 部分将在元表的成员上执行,并且会在 primaryGradient 的第一个元素中存储一个值, _从元表中_。

setPrimary 没有出现同样的问题的原因非常简单。self.primary 是一个操作。因为它是一个表访问和一个赋值操作,Lua 不会使用 __index 元方法。它将使用 __newindex 元方法。由于你没有定义 self 的元表的 __newindex,它将使用默认逻辑:在 self 中创建一个新成员并设置其值。

setPrimaryGradient 没有使用 __newindex 的原因是它确实使用了。只不过不是用于访问 self。它在 self["primaryGradient"] 的访问中使用了 __newindex;只有_最后_一个表访问才会调用 __newindex

如果你想使用默认值来初始化你的类型,以便你可以修改它们,你需要_复制_这些值。你有时不能只引用全局值。好吧,你可以,但设置它们会非常麻烦。

2013-03-17 01:12:37
用户1847592
用户1847592

问题可以通过以下方式轻松解决:

颜色= {
        primary = "BF2626",
        primaryGradient = {"CC2929", "B32424"}
        }
颜色.primaryGradient.__index = 颜色.primaryGradient

function 颜色:新建(o)
  o = o or {primaryGradient = setmetatable({}, self.primaryGradient)}
  setmetatable(o, self)
  self.__index = self
  return o
end
2013-03-17 06:40:10