2

我对 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为每个对象保留其值但表没有?
谢谢。

4

2 回答 2

3

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

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

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

第一部分,self["primaryGradient"]将检查self表并获取它的primaryGradient成员。问题是因为self有一个__index元方法,并且没有直接的primaryGradient成员self,所以它会__index直接使用元方法。所以它将primaryGradient 从 metatable中获取。共享的元表。

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

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

setPrimaryGradient不使用的原因__newindex是因为它确实使用了。只是不是为了访问self. 它用于__newindex访问self["primaryGradient"];只有最后一个表访问得到__newindex调用。

如果你想用一些可以修改的默认值来初始化你的类型,你需要复制这些值。有时你不能只引用全局的。好吧,你可以,但是设置起来会很痛苦。

于 2013-03-17T01:12:37.977 回答
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
于 2013-03-17T06:40:10.600 回答