2010-06-25 49 views
3

我對Lua有點新(對此還沒有真正做過很多),我正在嘗試圍繞metatables進行思考。我曾讓他們工作過,但現在(幾個月後)我遇到了一些非常奇怪的事情。Lua metamethods不被稱爲

該腳本在運行時應該打印什麼?

__mt = {} 

__mt.__index = function(table, key) 
    print("In __index") 
    return 99 
end 

test = {} 
test.x = 5 

setmetatable(test, __mt) 

print(test.x) 

就個人而言,我希望它遵循打印「在__index」(從元方法)由99但是,每當我運行它,我得到5.沒有我這樣做可以得到索引元方法來運行。它就像我使用rawget()來代替。

奇怪的是,加入

print(getmetatable(test).__index(test, "x")) 

會做正確的事。 metatable在那裏,__index()是正確的,它只是沒有被調用。

這是一個錯誤還是我只是在做一些愚蠢的事情?我不知道。

回答

8

元方法(在舊的術語也被稱爲回退)稱爲__index如果鍵x不存在於表中,當您訪問t.x只調用。改爲嘗試print(t.y)

補充:是的,使用代理表。

function doubletable(T) 
    local store = T or {} 
    local mt = {} 
    mt.__index = function (t, k) return store[k] and 2*store[k] end 
    mt.__newindex = store 
    return setmetatable({}, mt) 
end 

t = doubletable({a=1, b=3}) 
t.c = 7 
print(t.a, t.b, t.c) 
-- output: 2 6 14 
+0

啊,所以我在做一些愚蠢的事情。以前我在空表上使用自定義索引方法。是否有返回存儲數據的函數的方法(例如,存儲的2x是什麼)? – 2010-06-25 23:56:57

+1

您將不得不使用隱藏的表格,如他在那裏的表格,並覆蓋__newindex指向隱藏的表格。那樣,你的事件可以隨時開火。我經常使用這種技術。 – Puppy 2010-06-26 09:35:17