1. 程式人生 > >成為Lua高手之metatable

成為Lua高手之metatable

離職後今天第一次去面試,結果遇到了全LUA的面試題,由於之前使用LUA的時候都是做的介面邏輯並沒有深入的學習,結果直接傻眼了,果斷吃癟。

記錄一下遇到的問題,拓展下自己的知識面。

原文地址 http://www.cnblogs.com/vokie/p/3640550.html

metatable是我用Lua語言一段時間都沒有搞的很明白的東西。

再次遇到,就決心要和metatable敘敘感情。

首先談談元方法metaFunction有哪些:

add, sub, mul, div, mod, pow, unm, concat, len, eq, lt, le, tostring, gc, index, newindex, call...

使用的時候記得在元方法前面加上2條下劃線:例如:index  ->   __index

說說__index的使用:

local t1 = {}
function t1.showInfo()
  print("t1.showInfo Method~")
end

local t2 = {}
setmetatable(t2, {__index = t1})
t2.showInfo()

上面的程式碼我建立了2個表t1,t2.

將{__index = t1}設定為t2的metatable.

這個時候呼叫t2的showInfo方法,可以看到的結果是:

突然間,有沒有一種繼承的感覺:P

程式的運作大概是這樣的:

程式首先找t2的showInfo方法,結果沒找到,然後看t2有元表存在,

然後根據t2元表中的__index屬性的找到t2的"父類"t1表,並且找到了showInfo方法,故呼叫之。

再看如何通過__index建立我們自己的類。看程式碼:

local Car = {}

Car.__index = Car 

function Car:new( o )
  o = o or {}
  setmetatable(o, Car)
  return o
end

function Car:run()

end

...

...

...

分析上面的程式碼是如何建立我們自己的一個類,首先是建立了Car的table表,然後把Car的table表的__index設定為自己本身。

然後在假如我們需要建立一個新的類,local myCar = Car.new()

我們在Car的new方法中的工作是,需要注意的是:

我們傳了一個引數o,這個o就是Car的self原型,也就是上面我們建立的: local Car = {}  這張表,

如果o不存在,就新建一個o的空表,然後將o的metatable設定為Car,其實上面的程式碼,

可以合併成一個:

setmetatable(o,{__index = Car})

上面的一句話,相當於o表已經繼承了父類Car了,當o類中沒有的方法時,他會去父類Car中找。

所以當我們呼叫myCar.run();時,就可以成功的呼叫Car的run方法了。

回過頭來,想想metatable。

作為一個table,總有他的metatable的,當我們的table進行相關運算處理時,會尋求metatable的幫助,如果metatable能幫助table

來解決問題,那是最好不過了。

table是一棵樹,那麼metatable就好似樹的影子,他們是分主次關係的。

看大神的說法是:”樹“叫做本表,”樹“的影子叫做虛表。感覺更準確哦~

繼續幹活了。。。還想繼續深層探討,但是。。。下次遇到再學習~