我正在學習Lua,使用Lua中的編程,第一版。我無法理解metatables。在Lua中編程的第108頁中對Lua元表達式感到困惑
這是代碼,並出現108頁面上的解釋:
Set = {} function Set.new (t) local set = {} for _, l in ipairs(t) do set[l] = true end return set end function Set.union (a,b) local res = Set.new{} for k in pairs(a) do res[k] = true end for k in pairs(b) do res[k] = true end return res end function Set.intersection (a,b) local res = Set.new{} for k in pairs(a) do res[k] = b[k] end return res end
爲了幫助檢查我們的例子中,我們也可以定義一個函數來打印設置:
function Set.tostring (set) local s = "{" local sep = "" for e in pairs(set) do s = s .. sep .. e sep = ", " end return s .. "}" end function Set.print (s) print(Set.tostring(s)) end
現在,我們想要使加法運算符(
+
)計算兩個集合的並集。爲此,我們將安排所有代表集合的表共享一個metatable,並且這個metatable將定義他們對加法運算符的反應。我們的第一步是創建一個常規表格,我們將用它作爲集合的元數據。爲了避免污染我們的命名空間,我們將其存儲在設置表:Set.mt = {} -- metatable for sets
下一步是修改Set.new功能,創建集。新版本只有一個額外的行,這臺MT的元表的表,它創建:
function Set.new (t) -- 2nd version local set = {} setmetatable(set, Set.mt) for _, l in ipairs(t) do set[l] = true end return set end
之後,每一套我們與Set.new創建將具有相同的表的metatable:
s1 = Set.new{10, 20, 30, 50} s2 = Set.new{30, 1} print(getmetatable(s1)) --> table: 00672B60 print(getmetatable(s2)) --> table: 00672B60
最後,我們增加了元表所謂的元方法,描述如何執行工會場__add:
Set.mt.__add = Set.union
每當Lua中嘗試添加兩套,它會調用這個函數用兩個操作數作爲參數。
有了元方法,我們可以使用加法運算做一套工會:
s3 = s1 + s2 Set.print(s3) --> {1, 10, 20, 30, 50}
當我試圖運行它,我得到的結果是:在s3
{ union, mt, intersection, tostring, new, print}
,而不是數字。似乎我打印了metatables的內容。有人可以解釋這裏發生了什麼嗎?這本書描述了5.0版本,我正在使用Lua 5.1。這是否會造成這種情況?
在你的文章中你的代碼的格式似乎有些不對。 –
我剛剛嘗試了http://www.lua.org/pil/13.1.html中的代碼,並且它在Lua 5.1中正常工作。 – lhf