什麼是元表:
對Lua來說,元表只是另一個表,沒有特殊之處。任何表都可以作爲其他表的元表,元表也可以擁有元表,甚至可以自身作爲自己的元表。
可以通過getmetatable()和setmetatable()來獲取和設置元表,示例:
x = {} -- 一張空表x
print(getmetatable(x)) -- 獲得結果nil,因爲x沒有元表
y = {}
setmetatable(x, y) -- 設置y表爲x表的元表
if getmetatable(x) == y then
print("Success")
else
print("Fall")
end
更有趣的元方法_index:
其實我一點都不覺得有趣,書上這麼說的。。。
假設你這麼寫:
x = {}
print(x.y)
1.那麼你得到的結果將會是nil,因爲x並沒有y這個字段。
2.但是在沒有的時候,Lua就會檢查這個表x是否有元表,如果有元表,那麼就會去檢查元表中的_index方法
3.如果有index方法,就會調用它並將返回結構作爲y的值
4.如果_index是另一個表,Lua就會嘗試對它進行相同的訪問,是否有該字段,是否有元表等
5.實在是沒有了,就會返回nil
以下是示例:
Vec3 =
{
x=25, y=0, z=0
}
function Verctor3:Length()
return math.sqrt((self.x * self.x) + (self.y * self.y) + (self.z * self.z));
end
v = { _index = Vec3 }
setmetatable(v, v) -- 設置自己爲元表
print(v.x) -- 那麼這裏得到的值就是Vec3的x,值爲25
但是要注意,這隻會影響值的讀取,並不會影響寫入,寫入有一個單獨的元方法_newvalue
在沒有_newvalue時,繼續寫下去:
v.x = 10; -- 這時問題來了,沒有_newvalue,所以Lua將設置v.x的值爲10,而不會修改Vec3中的值