2012-04-12 46 views
1

我試圖創建一個表示矩陣的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) 

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 

回答

3
object = object or {} 

這就是爲什麼出現這種情況。您只創建一個矩陣對象。您只返回每個表格object,並且您只有一個self表格用作metatable。

那麼,如何在Matrix:New每次調用時都會返回完全相同的值的情況下預期不同的實例?

您需要爲每個New調用返回一個新的表;這就是爲什麼我們使用這個名稱;)由於您使用metatable的方式,您還必須返回一個新的metatable;你不能返回附加到新表的相同metatable,並期望它工作。

+0

那好吧,我把新的方法從編程在Lua中,也許我沒有正確地實現它。我將如何解決這個問題? – RedShft 2012-04-12 22:52:45

+1

@RedShft:我會建議回頭看看「Lua編程」和*理解*它在做什麼以及它爲什麼這樣做,而不是僅僅複製和粘貼代碼。它使用元表中沒有被使用的方式你(有PIL,它的存儲數據的對象;所述元表只存儲特定功能並且這樣的)。另外,PIL的'new'函數可以選擇一個對象作爲參數;這就是爲什麼他們做了「o = o或{}」的事情。你的函數只是使用一個名爲'object'的全局變量,因爲你忘記把'object'作爲參數。請注意,這不會解決您的問題。 – 2012-04-12 22:58:30

+0

你拒絕向我解釋?好。 – RedShft 2012-04-12 23:03:04

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已經被設置爲它的元表。

相關問題