1

マトリックスを表す Lua テーブルを作成しようとしていますが、2 つのマトリックスを作成し、いくつかの値を初期化すると、両方とも同じ値になるという問題が発生し続けます。

--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 オブジェクトを1 つだけ作成します。object返すテーブルはすべて 1 つだけでありself、メタテーブルとして使用するテーブルは 1 つだけです。

Matrix:Newでは、すべての呼び出しで常にまったく同じ値を返す異なるインスタンスをどのように期待できますか?

呼び出しごとに新しいテーブルを返す必要があります。Newそのため、この名前を使用しています ;) メタテーブルの使用方法により、新しいメタテーブルも返す必要があります。新しいテーブルにアタッチされた同じメタテーブルを返して、それが機能することを期待することはできません。

于 2012-04-12T22:49:22.150 に答える
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

于 2012-04-13T10:58:28.047 に答える