Lua元表
在Lua中,我們可以通過(guò)key找到對(duì)應(yīng)的value值,但是無(wú)法對(duì)兩個(gè)table進(jìn)行操作。
在Lua中為我們提供了元表(Metatable),允許我們改變table的行為,每個(gè)行為關(guān)聯(lián)了對(duì)應(yīng)的元方法
- setmetatable(table,metatable) 對(duì)指定的table設(shè)置元表。如果元表存在_metatable鍵值,則方法會(huì)失敗。
- getmetatable(table)得到對(duì)象的原表
為一個(gè)表設(shè)置其對(duì)應(yīng)的原表
setmetatable(mytable,metatable) function返回mytable。即為哪個(gè)原始表設(shè)置的元表
getmetatable(mytable) function返回metatable
index元方法。當(dāng)我們?nèi)ヒ粋€(gè)表去查找一個(gè)字段的時(shí)候,如果存在則直接返回。如果不存在的話,則去其對(duì)應(yīng)的元表中去尋找 __index key,如果對(duì)應(yīng)的是一個(gè)表的話,則去這個(gè)index對(duì)應(yīng)的表中去尋找。找到則返回
table = {key=david}
othertable = {other=3}
setmetatable(table,{__index=othertable})
print(table.key);
print(table.other)
-
去metatable去尋找__index對(duì)應(yīng)的是不是一個(gè)function。如果是的話,則把表本身和key傳入。
nativetable = {key='david'} setmetatable(nativetable,{__index=function (table,key) if key == 'key2' then return '牛B' else return nil end end }) print(nativetable.key) print(nativetable.key2) -
使用__newIndex的方式可以對(duì)傳入未知的key保存到 newIndex對(duì)應(yīng)的表中,不進(jìn)行直接的賦值??梢酝ㄟ^(guò) rawset 函數(shù)來(lái)更新表。
mytable = setmetatable({key1 = "value1"}, { __newindex = function(mytable, key, value) rawset(mytable, key, "\""..value.."\"") end }) mytable.key1 = "new value" mytable.key2 = 4 print(mytable.key1,mytable.key2) -
使用__add的方式,使2個(gè)表相加
-- 計(jì)算表中最大值,table.maxn在Lua5.2以上版本中已無(wú)法使用 -- 自定義計(jì)算表中最大鍵值函數(shù) table_maxn,即計(jì)算表的元素個(gè)數(shù) function table_maxn(t) local mn = 0 for k, v in pairs(t) do if mn < k then mn = k end end return mn end -- 兩表相加操作 mytable = setmetatable({ 1, 2, 3 }, { __add = function(mytable, newtable) for i = 1, table_maxn(newtable) do table.insert(mytable, table_maxn(mytable)+1,newtable[i]) end return mytable end }) secondtable = {4,5,6} mytable = mytable + secondtable for k,v in ipairs(mytable) do print(k,v) end -
__tostring 元方法用于修改表的輸出行為
mytable = setmetatable({ 10, 20, 30 }, { __tostring = function(mytable) sum = 0 for k, v in pairs(mytable) do sum = sum + v end return "表所有元素的和為 " .. sum end }) print(mytable)