這是一種有約會經驗的Lua程序員推薦的方法嗎?還是有真正的優點來做到這一點?
這不是典型的。優點是對象狀態是私有的,但這不足以推薦它。
我反覆看到這種模式。
我從來沒有見過它,它只發生在您發佈的源中一次。
編輯:添加一個迴應問題在這篇文章下面的評論問。
訪問外部局部變量的函數將綁定到這些變量並稱爲'閉包'。 Lua(出於歷史原因)將這些約束變量稱爲「upvalues」。例如:
local function counter()
local i = 1
return function()
print(i)
i = i + 1
end
end
local a, b = counter(), counter()
a() a() a() b() --> 1 2 3 1
a
和b
被封鎖必然的i
不同的副本,你可以從輸出中看到。換句話說,你可以將閉包看作是它自己的私有狀態的函數。你可以用它來模擬對象:
function Point(x,y)
local p = {}
function p.getX() -- syntax sugar for p.getX = function()
return x
end
function p.setX(x_)
x = x_
end
-- for brevity, not implementing a setter/getter for y
return p
end
p1 = Point(10,20)
p1.setX(50)
print(p1.getX())
Point
返回關閉表,每個綁定當地人x
和y
。該表不包含點的狀態,封閉本身通過它們的upvalues。重要的一點是,每次調用Point
時,都會創建新的閉包,如果您擁有大量對象,則閉包效率不高。
在Lua創建類的另一種方法是創建存儲在表中使用表作爲第一個參數的功能,與國家:
function Point(x,y)
local p = {x=x,y=y}
function p:getX() -- syntax sugar for p.getX = function(self)
return self.x
end
function p:setX(x)
self.x = x
end
return p
end
p1 = Point(10,20)
p1:setX(50) -- syntax sugar for p1.setX(p1, 50)
print(p1:getX()) -- syntax sugar for p1.getX(p1)
到目前爲止,我們仍然創造的新副本每一種方法,但現在我們不依靠upvalues的狀態,我們可以解決這個問題:
PointClass = {}
function PointClass:getX() return self.x end
function PointClass:setX(x) self.x = x end
function Point(x,y)
return {
x = x,
y = y,
getX = PointClass.getX,
setX = PointClass.getY,
}
end
現在的方法是創建一次,所有Point
實例共享相同的瓶蓋。這樣做的更好的方法是使用Lua的元編程設施,使新Point
情況下自動尋找在PointClass
在實例本身未找到方法:
PointClass = {}
PointClass.__index = PointClass -- metamethod
function PointClass:getX() return self.x end
function PointClass:setX(x) self.x = x end
function Point(x,y)
return setmetatable({x=x,y=y}, PointClass)
end
p1 = Point(10,20)
-- the p1 table does not itself contain a setX member, but p1 has a metatable, so
-- when an indexing operation fails, Lua will look in the metatable for an __index
-- metamethod. If that metamethod is a table, Lua will look for getX in that table,
-- resolving p1.setX to PointClass.setX.
p1:setX(50)
這是在Lua創建類的更地道的方式。它具有更高的內存效率和更高的靈活性(特別是,它可以很容易地實現繼承)。
你確定你已經簡化了它嗎?你能以完整的形式鏈接到這些例子嗎? – Amber 2010-12-11 22:51:32
是的,你發佈的'模式'似乎完全沒有意義。你說你看到「很多」,你能鏈接到一個例子嗎? – Mud 2010-12-12 01:38:15
我用一個更完整的例子編輯了這個問題,並引用了你可以下載完整的源代碼檔案的地方。如果Lua與我所知道的其他語言一樣,看起來第二種形式可以少花錢。 – 2010-12-12 04:33:47