即使是新对象,Lua 表变量仍然相同

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

--Test.Lua
require"Matrix"

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

M1._11 = 2

print(M1._11) --打印 2
print(M2._11) --打印 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

原文链接 https://stackoverflow.com/questions/10132909

点赞
stackoverflow用户734069
stackoverflow用户734069
对象 = 对象或 {}

这就是发生的原因。您只创建了_一个_ 矩阵对象。只有一个对象表,您返回它,只有一个self表,您用作元表。

那么,当Matrix:New始终在每个调用上返回完全相同的值时,您如何期望不同的实例呢?

您需要为每个New调用返回一个_新_ 表;这就是我们为什么使用那个名称的原因 ;)由于您正在使用元表,因此还必须返回一个新元表;您不能返回附加到新表的相同元表并期望它有效。

2012-04-12 22:49:22
stackoverflow用户312586
stackoverflow用户312586

如nicol所解释的,一方面你正在尝试“反复重用同一个对象”(可能是为了“使其更快”),另一方面你想要有不同的对象。

解决方案是 - 在New调用中不要重用object

local Matrix = {} -- 不要使用模块函数。将Matrix设为local变量...
Matrix.__index = Matrix

function Matrix:New()
    local object = { -- 每次调用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 -- ...并在最后返回Matrix的本地变量

一些注意事项:

  • 你真的必须学会如何使用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)返回已将m设置为其元表的t

2012-04-13 10:58:28