1

我正在尝试创建一个表示矩阵的 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 
4

2 回答 2

3
object = object or {}

这就是为什么会发生这种情况。您只能创建一个Matrix 对象。object您返回的只有一张表self,并且您只使用一张表作为元表。

那么你怎么能期望不同的实例Matrix:New在每次调用时总是返回完全相同的值呢?

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

于 2012-04-12T22:49:22.150 回答
1

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

解决方案是 - 不要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

于 2012-04-13T10:58:28.047 回答