Lua表变量即使对于新对象也是相同的
我试图创建一个表示矩阵的Lua表,但是我一直遇到一个问题,如果我创建两个矩阵,并初始化一些值,它们都有相同的值Lua表变量即使对于新对象也是相同的,lua,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) Mat
--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
这就是为什么会发生这种情况。只能创建一个矩阵对象。您返回的每个对象
表只有一个,而您用作元表的self
表也只有一个
那么,当Matrix:New
每次调用都返回完全相同的值时,您怎么能期望不同的实例呢
您需要为每个new
调用返回一个新表;这就是为什么我们用这个名字;)由于使用元表的方式,还必须返回一个新的元表;不能返回附加到新表的同一元表并期望它工作
这就是为什么会发生这种情况。只能创建一个矩阵对象。您返回的每个对象
表只有一个,而您用作元表的self
表也只有一个
那么,当Matrix:New
每次调用都返回完全相同的值时,您怎么能期望不同的实例呢
您需要为每个
new
调用返回一个新表;这就是为什么我们用这个名字;)由于使用元表的方式,还必须返回一个新的元表;您不能返回附加到新表的同一元表并期望它工作。正如nicol所解释的,一方面您试图“反复使用同一对象”(可能是为了“使其更快”),另一方面您希望拥有不同的对象
解决方案是-不要在新调用时重用对象
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: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
已经设置为其元表。正如nicol所解释的,一方面,您试图“反复使用相同的对象”(可能是为了“使其更快”),另一方面,您希望拥有不同的对象
解决方案是-不要在新调用时重用对象
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: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
已经设置为其元表。哦,好吧,我从Lua编程中获得了这个新方法,可能我没有正确实现它。我该如何解决这个问题?@RedShft:我建议回顾一下“Lua中的编程”,了解它在做什么以及为什么要这么做,而不仅仅是复制和粘贴代码。它使用的元表中没有一个是像您使用的那样使用的(对于PIL,它是存储数据的对象;元表只存储某些函数等等)。此外,PIL的new
函数可选地将对象作为参数;这就是为什么他们做了o=o或{}
的事情。您的函数只是使用了一个名为object
的全局变量,因为您忘记将object
作为参数。请注意,这并不能解决您的问题。您拒绝向我解释吗?好的。哦,好的,我从Lua编程中得到了这个新方法,也许我没有正确地实现它。我该如何解决这个问题?@RedShft:我建议回顾一下“Lua中的编程”,了解它在做什么以及为什么要这么做,而不仅仅是复制和粘贴代码。它使用的元表中没有一个是像您使用的那样使用的(对于PIL,它是存储数据的对象;元表只存储某些函数等等)。此外,PIL的new
函数可选地将对象作为参数;这就是为什么他们做了o=o或{}
的事情。您的函数只是使用了一个名为object
的全局变量,因为您忘记将object
作为参数。请注意,这并不能解决您的问题。您拒绝向我解释吗?好啊