Lua Metatable

Lua

Metatable

元表就是一個集合了{__index, __add, __call}之類函數的表。 我把他理解爲在某個表內 內嵌的一個隱藏的表。只有在查找失敗的時候會用到,而且在查找失敗的時候並不是調用這個“隱藏表”裏的函數,而是這個“隱藏表”裏__index裏面裝的函數。

如果一個元素有元表,則查詢某個鍵的過程變爲
- 若表內存在該鍵,返回值;若不存在,進行下一步
- 若表內存在元表,進行下一步;返回nil
- 若元表內的__index裏有值,對__index執行第一步

-- top is actually {v = 1, top = 'top',  __index = table-top, metatable = nil }
top = {}
top.__index = top
top.top = 'top'
top.v = 1
print('======= TOP ========')
print('top.top = ' .. top.top)
print('top.v = ' .. top.v)

--                                                                                          {v = 1,  top = 'top', __index = table-top, *hidden_table* = nil } 
--                                                                                                 ^                                                             
--  mid is actually {v = 2, __index = table-mid, metatable =       |                                                                                          }
mid = {}
mid.__index = mid
mid.v = 2
setmetatable(mid, top)
print('======= MID ========')
print('mid.top = ' .. mid.top) -- find failed, try to locate metatable.__index.top, which equals top.top
print('mid.v = ' .. mid.v)
print('mid.super.v = ' .. getmetatable(mid).v)

--                                                                                                          {v = 1,  top = 'top', __index = table-top, *hidden_table* = nil } 
--                                                                                                                   ^                                                             
--                                             {v = 2, __index = table-mid, metatable =       |                                                                                          }
--                                                                            ^
-- bot is { v = 3, __index = table-bot, metatable =  |                                                                                                                                      }
bot = {}
bot.__index = bot
bot.v  = 3
setmetatable(bot, mid)
print('======= BOT ========')
print('bot.top = ' .. bot.top) 
print('bot.v = ' .. bot.v)
print('bot.super.v = ' .. getmetatable(bot).v)
print('bot.super.super.v = ' .. getmetatable(getmetatable(bot)).v)

輸出結果

======= TOP ========
top.top = top
top.v = 1
======= MID ========
mid.top = top
mid.v = 2
mid.super.v = 1
======= BOT ========
bot.top = top
bot.v = 3
bot.super.v = 2
bot.super.super.v = 1

Inherit

自己寫了一個雞肋的繼承,繼承的基本結構是(箭頭表示元表指向)
mid -> Mid -> Top
mid 同時持有Mid和Top的成員變量,與c++不同的是:對於同名成員變量,這裏僅保存子類的值。

Top = {}
Top.__index = Top
function Top:create(v)
    local top = {}
    top.v = v
    setmetatable(top, Top)
    return top
end

function Top:print()
    print("this is top")
    print("v = " .. (self.v or 'nil'))
    print("x = " .. (self.x or 'nil'))
end

Mid = {}
Mid.__index = Mid
setmetatable(Mid, Top)
function Mid:create(v, x)
    -- mid -> Mid -> Top
    local mid = Top:create(0)
    setmetatable(mid,  Mid)
    mid.v = v
    mid.x = x
    return mid
end
function Mid:print()
    print("this is mid")
    print("v = " .. (self.v or 'nil?'))
    print("x = " .. (self.x or 'nil?'))
    Top.print(self)
end

top = Top:create(1)
mid =  Mid:create(2, 3)

mid:print()

輸出結果爲

this is mid
v = 2
x = 3
this is top
v = 2
x = 3
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章