2012-04-12 47 views
1

我试图创建一个表示矩阵的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 

回答

3
object = object or {} 

这就是为什么出现这种情况。您只创建一个矩阵对象。您只返回每个表格object,并且您只有一个self表格用作metatable。

那么,如何在Matrix:New每次调用时都会返回完全相同的值的情况下预期不同的实例?

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

+0

那好吧,我把新的方法从编程在Lua中,也许我没有正确地实现它。我将如何解决这个问题? – RedShft 2012-04-12 22:52:45

+1

@RedShft:我会建议回头看看“Lua编程”和*理解*它在做什么以及它为什么这样做,而不是仅仅复制和粘贴代码。它使用元表中没有被使用的方式你(有PIL,它的存储数据的对象;所述元表只存储特定功能并且这样的)。另外,PIL的'new'函数可以选择一个对象作为参数;这就是为什么他们做了“o = o或{}”的事情。你的函数只是使用一个名为'object'的全局变量,因为你忘记把'object'作为参数。请注意,这不会解决您的问题。 – 2012-04-12 22:58:30

+0

你拒绝向我解释?好。 – RedShft 2012-04-12 23:03:04

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已经被设置为它的元表。

相关问题