我想了解這個函數做什麼。任何人都可以向我解釋這個嗎?試圖瞭解這個lua片段
function newInstance (class)
local o = {}
setmetatable (o, class)
class.__index = class
return o
end
它被稱爲是這樣的:
self = newInstance (self)
我想了解這個函數做什麼。任何人都可以向我解釋這個嗎?試圖瞭解這個lua片段
function newInstance (class)
local o = {}
setmetatable (o, class)
class.__index = class
return o
end
它被稱爲是這樣的:
self = newInstance (self)
這個功能顯然是用來提供OOP的Lua中的一個變種(有點邋遢在我看來)。
這是一個班的工廠。
可能被改寫如下,爲了清楚:
C = { }
C.foo = function(self) -- just some method, so class would not be empty
print("foo method called", tostring(self))
end
C.__index = C -- (A)
function newInstance(class)
return setmetatable({ }, class) -- (B)
end
現在,如果我們創建C的兩個新實例,我們清楚地看到,無論是有一個方法foo(),但不同的自我:
o1 = newInstance(C)
o1:foo() --> foo method called table: 0x7fb3ea408ce0
o2 = newInstance(C)
o2:foo() --> foo method called table: 0x7fb3ea4072f0
foo的方法是相同的:
print(o1.foo, o2.foo, o1.foo == o2.foo and "equal" or "different")
--> function: 0x7fb3ea410760 function: 0x7fb3ea410760 equal
這是因爲表C(所述 「類」)是__index
((A)
以上)的元數據o1
和o2
,設置在(B)
中。但o1
和o2
實際上是兩個不同的表格,創建於(B)
(「類實例」或「對象」)。
注意:我們設置C.__index
等於C
本身在(A)
,所以我們將重用一個表。以下具有相同的效果:
prototype = { }
prototype.foo = function(self) -- just some method, so class would not be empty
print("foo method called", tostring(self))
end
C = { __index = prototype }
function newInstance(class)
return setmetatable({ }, class)
end
o = newInstance(C)
這是用來在Lua中實現面向對象的行爲。 Lua使用基於原型的繼承(類似於Javascript)而不是基於類的繼承(如Java或C++)。 這個想法是,所有的類方法都是作爲原型對象的一部分實現的,並且在調用時繼承對象委託給原型。
例如,假設你想有一個類myClass
提供的方法getMagicNumber
:
local myClass = {
getMagicNumber = function(self)
return self.theNumber;
end };
local obj = newInstance(myClass);
obj.theNumber = 42;
print(obj:getMagicNumber()); -- supposed to return 42
這是怎樣的一個簡單的例子,但我希望你的想法。會發生什麼事情是這樣的:newInstance創建一個新的表,它的metatable指向myClass
,並且還確保metatable的__index
字段也指向myClass。 正如__index
上的Lua手冊所述,當您現在嘗試在該新表上調用getMagicNumber時,會發生以下情況:第一個Lua嘗試在obj
表中查找字段getMagicNumber
。由於該表是空的,因此它現在搜索該表的__index
表(myClass
)。由於該字段在那裏找到,它現在調用myClass
中的函數。
Programming in Lua如果您需要了解更多信息,請詳細討論此機制。
你並不孤單,我花了相當一段時間來琢磨這段代碼。下面是我的解釋
每個表只能有一個netatable,元表可以存儲之間按名稱索引的其他東西的功能,並setmetatable集的元表很自然的價值。
line class._index = ..是魔法發生的地方。
當您嘗試調用一個函數使用self.fn1(),然後LUA查找在自我的名稱FN1。如果它找不到它,那麼它在表格__index
中查找self的metatable,並在存儲的表中查找'fn1'。
現在你的例子中的metatable for self是class,所以lua在metatable(class)中尋找一個__index條目來查看錶中是否有名爲fn1的函數,並且有返回。您需要將類的__index設置回自己,以便lua將查看相同的metatable - 令人困惑的嘿。 (作爲__index的賦值只需要發生一次,但由於某種原因,它總是在所有lua示例中的新運算符中完成的 - 我將它放在我的類中的新運算符之外 - 節省了幾個循環)
然後你返回新表o,lua是垃圾收集,所以每次返回一個本地創建一個新表。
function newInstance (class)
local o = {}
setmetatable (o, class)
class.__index = class
return o
end
心連心
請人提供更好的標題這個問題,因爲我認爲這將有助於一些開發商在那裏。 – chchrist 2012-03-09 09:25:20