对于新对象,Lua表变量相同

时间:2012-04-12 22:41:51

标签: lua

我正在尝试创建一个表示矩阵的Lua表,但是我一直遇到一个问题,如果我创建两个矩阵,并初始化一些值,它们都具有相同的值。

--Test.Lua
require"Matrix"

M1 = Matrix.Matrix:New()
M2 = Matrix.Matrix:New()

M1._11 = 2

print(M1._11) --Prints 2
print(M2._11) --Prints 2


--Matrix.lua

module("Matrix", package.seeall)

Matrix = {}

Matrix = {  _11 = 0, _12 = 0, _13 = 0,
        _21 = 0, _22 = 0, _23 = 0,
        _31 = 0, _32 = 0, _33 = 0
    }

function Matrix:New()
    object = object or {}
    setmetatable(object, self)
    self.__index = self
    return object
end 

2 个答案:

答案 0 :(得分:3)

object = object or {}

这就是发生这种情况的原因。您只需创建一个 Matrix对象。您返回的每个object表只有一个,并且只有一个self表用作元表。

那么,当Matrix:New在每次通话时总是返回完全相同的值时,你怎么能指望不同的实例呢?

您需要为每个New电话返回表格;这就是我们使用该名称的原因;)由于您使用metatable的方式,您还必须返回一个新的元表;你不能返回附加到新表的相同元表并期望它能够工作。

答案 1 :(得分:1)

正如尼科尔所解释的那样,一方面你试图“一遍又一遍地重复使用同一个对象”(可能是为了“让它更快”)而另一方面你想要拥有不同的对象。

解决方案是 - 不要在新呼叫上重复使用object

local Matrix = {} -- don't use the module function. Make Matrix local ...
Matrix.__index = Matrix

function Matrix:New()
    local object = { -- create one local variable on every call to New
        _11 = 0, _12 = 0, _13 = 0,
        _21 = 0, _22 = 0, _23 = 0,
        _31 = 0, _32 = 0, _33 = 0
    }   
    setmetatable(object, self)
    return object
end

return Matrix -- ... and return the Matrix local var at the end

一对夫妇注意到:

  • 您真的必须学习如何使用local
  • 建议不要使用模块功能。返回一个本地表,如我的例子所示。

用法:假设该文件名为“Matrix.lua”:

local Matrix = require 'Matrix'

local M1 = Matrix:New()
local M2 = Matrix:New()
-- etc

作为旁注,Matrix:New()功能可以缩短(和更快)。以下实现与上面的实现完全相同,但效率稍高:

function Matrix:New()
    return setmetatable({
        _11 = 0, _12 = 0, _13 = 0,
        _21 = 0, _22 = 0, _23 = 0,
        _31 = 0, _32 = 0, _33 = 0
    },
    self)
end

这是有效的,因为setmetatable(t,m)返回tm已设置为其元表。