2013-08-22 35 views
3

我正在學習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。這是否會造成這種情況?

+1

在你的文章中你的代碼的格式似乎有些不對。 –

+0

我剛剛嘗試了http://www.lua.org/pil/13.1.html中的代碼,並且它在Lua 5.1中正常工作。 – lhf

回答

2

有在the code you ran的錯誤,而不是在你的代碼已經發布的問題:

Set.tostring 28行,你改變了for e in pairs(set)for e in pairs(Set),所以它總是顯示的Set,而不是內容給定集的內容。

+0

謝謝,但那不是。我重新檢查過它,並且我寫了Set.print(s3)。任何其他想法? – maxam

+0

http://codepad.org/DSncIL43#comment-9Yzx0fPZ – maxam

+0

就是這樣!非常感謝!這是我第二次在lua中發現了一個令人討厭的錯誤,我錯誤地打印了一封信並且整個代碼變得糟糕透了。在我看來,這是因爲lua區分大小寫,同時允許使用變量而不實際初始化它們。 – maxam