【问题标题】:Does Lua share tables within tables?Lua 是否在表内共享表?
【发布时间】:2014-07-26 22:11:52
【问题描述】:

我开始使用 Love2d 引擎和 Lua 开发游戏,我有以下代码结构。

BaseEntity = { 
        x = 0,
        y = 0,
        w = 0,
        h = 0,
        img = {},
     }

function BaseEntity:new(obj)
    obj = obj or {}
    setmetatable(obj, self)
    self.__index = self
    return obj
end

function BaseEntity:setPos(x, y)
    self.x = x
    self.y = y
end

function BaseEntity:setImage( index, image )
    self.img[index] = image
end

PlayerType  = {["NORMAL"] = 0, ["AI"] = 1}
PlayerState = {["SELECTED"] = 0, ["NOT_SELECTED"] = 1}

Player =    {
                type    = PlayerType.NORMAL,
                state   = PlayerState.NOT_SELECTED
            }

Player = BaseEntity:new(Player)

function Player:new( obj )
    obj = obj or BaseEntity:new()
    setmetatable(obj, self)
    self.__index = self
    return obj
end

function Player:setImage( image )
    self.img["sprite"] = image
end

当我创建几个 Player 对象并使用 setImage() 函数为每个对象分配不同的图像时,它们都共享我分配给最后一个对象的相同图像。但是当我使用setPos() 方法为每个对象设置不同的位置时,它们被绘制在正确的独特位置。为什么会这样? Lua 是否与在 BaseEntity 中创建的所有实例共享表 img

【问题讨论】:

  • 不要在BaseEntity 中包含img = {}。在构造函数BaseEntity:new(obj) 中创建img,而不是:obj.img = {} 就在return obj 之前
  • 这条线应该被吊出函数:self.__index = self
  • 更好地重新考虑您的继承框架。它被窃听了。

标签: lua lua-table love2d


【解决方案1】:

表格是共享的。如果您不想共享,则必须创建单独的表实例。请注意,您将 x, y ... img 定义为类变量而不是实例变量。要查看此内容,请尝试以下代码:

BaseEntity = { 
        x = 0,
        img = {}, 
     }

function BaseEntity:new(obj)
    obj = obj or {}
    assert(self == BaseEntity)
    setmetatable(obj, self)
    -- obj.img = {}
    self.__index = self
    -- self.__newindex = self
    return obj
end

p1 = BaseEntity:new {y = 1}
p2 = BaseEntity:new {y = 2}

print('p1:', p1.x, p1.y, p1.img)
print('p2:', p2.x, p2.y, p2.img)
print('base:', BaseEntity.x)
p1.x = 3
print('p1:', p1.x, p1.y, p1.img)
print('p2:', p2.x, p2.y, p2.img)
print('base:', BaseEntity.x)

这会产生这个输出:

p1: 0   1   table: 0x1736430
p2: 0   2   table: 0x1736430
base:   0
p1: 3   1   table: 0x1736430
p2: 0   2   table: 0x1736430
base:   0

显示该表是共享的,并且当您写入 x 时,您正在写入 p1 实例而不是类。如果现在取消注释new() 中的obj.img,p1 和p2 的表将不再相同:每个实例都有自己的。如果您取消注释 __newindex 行,您将看到您正在分配给 BaseEntity “类”

【讨论】:

  • 感谢您的精彩回答。我是 Lua 的新手,所以还是有点粗糙:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-13
  • 1970-01-01
  • 1970-01-01
  • 2016-03-29
  • 1970-01-01
相关资源
最近更新 更多