元表
元表就是允許我們改變table的行為,你所改變的這個行為又關聯(lián)了一個方法,這個方法我們稱作元方法(系統(tǒng)提供)既鞠。
t = {}
print(getmetatable(t)) ?-- nil ?因為沒有設置其元表
m_t = {
__tostring = function (t) ?--設置元方法
return "aa"
end
}
t1 = setmetatable(t,m_t)
print(t) -- aa
if(t == t1)
then
print("同一張表") --輸出,所以證明其實t和t1就是同一張表
end
第二種寫法
t = setmetatable({},{
__tostring = function (t)
return 111
end
})
print(t)
在lua中創(chuàng)建新的表或者是其他類型的時候,會為該類型提供元表,但是有一個特例就是字符串
t = 10
print(getmetatable(t)) -- nil
str = "hello"
print(getmetatable(str))--string自帶元表
常用創(chuàng)建元表的方式
setmetatable的兩個參數,第一個參數為改變行為的那張表,第二個參數是元表具體的改變行為
T = setmetatable({},{})
__add(t1,t2)? -- 相加行為
__sub(t1,t2)? -- 相減行為
__mul? ? ? ? -- 相乘行為
__div ? -- 相除行為
__len(t1)? ? -- 表的長度
__index? ? ? -- 索引查詢
__newindex? ? -- 更新索引
__tostring ? -- 字符串輸出
......
例子
Window = {}
Window.default = {
x = 0,
y = 0,
width = 100,
height = 100,
color = {
r = 255.0,
g = 255.0,
b = 255.0
}
}
--創(chuàng)建一個元表
Window.mt = {}
--構造函數
function Window.new(obj)
setmetatable(obj,Window.mt)
return obj
end
--__index元方法:查詢索引
Window.mt.__index = function (tb,key)
print("該方法被調用")
return Window.default[key]
end
-- Window.mt.__index = Window.default -- 指定表,如果表中沒有該字段,則去這個表中的元表中找,找到__index元方法,這個方法也可以對
--應一張表,只是這樣的話不能再做攔截的操作了
local win = Window.new({x = 10,y = 20})
print(win.x) --10
print(win.y) --20
print(win.width) -- 該方法被調用 100
print(win.height) -- 該方法被調用 100
print(win.x) 由于win變量本身就擁有了x字段,所以直接打印
print(win.width) 由于win變量沒有該字段,那么就去查找是否擁有元表,如果有,就去元表中查詢
先看元表中是否有__index元方法對應的方法或者表,
由于存在__index 所以返回default表中width字段
在實際開發(fā)中__index元方法不一定就對應的是函數,也有可能是表
最后總結一下 Lua 查找一個元素時候的規(guī)則
1.在表中查詢,如果找到返回該元素,找不到繼續(xù)
2.判斷該表是否具備元表,如果有繼續(xù),如果沒有返回nil
3.判斷元表是否具備某種行為,有繼續(xù),沒有nil