我正在尝试创建一个表示矩阵的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
答案 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)
返回t
,m
已设置为其元表。