lua元表和面向?qū)ο?/h1>

元表

首先lua中的number類型是可以執(zhí)行一些操作的霜浴,比如

1 + 1 //2
1 - 1 //0

如果我們定義兩個復(fù)數(shù)如下昨登,希望能實現(xiàn)其的加法

local a = {1, 2}
local b = {3, 4}
// 相加我們希望得到 {4, 6}

如果我們直接相加這兩個變量辜腺,lua解釋器會告訴我們有錯誤默勾。
這個時候我們就可以通過元表的方式來達到我們期望的結(jié)果碉渡,元表可以理解為一個元操作或者行為的集合∧赴可以通過 setmetatable 設(shè)置table的元表 getmetatable獲取任意變量的元表滞诺。一個新的table創(chuàng)建時元表為空形导。

表達式a+b,在Lua中是按照以下步驟進行的

  1. 先判斷a和b兩者之一是否有元表
  2. 檢查該元表中是否有一個叫__add的字段铭段;如果找到了該字段骤宣,就調(diào)用該字段對應(yīng)的值,這個值對應(yīng)的是一個方法序愚;

在Lua中,每個值都有一個元表等限,table和userdata類型的每個變量都可以有各自獨立的元表爸吮,而其他類型的值則共享其類型所屬的單一元表。

local m = {
    __add = function (a, b)
        return {a[1] + b[1], a[2] + b[2]}
    end
}
local a = setmetatable({1,2}, m)
local b = setmetatable({3,4}, m)
// 這時a + b 就會得到結(jié)果 {4, 6}

除了加法望门,元表中還有其他的操作如下表

Mode 描述
__add
__sub
__mul
__div
__mod 取余
__unm 取相反數(shù)
__concat 連接
__eq 等于
__lt 小于
__le 小于等于
__call 將table作為方法調(diào)用時會調(diào)用元表的__call
__tostring 將table作為string傳入時會調(diào)用元表的__tostring
__index 下面講
__newindex 下面講

__index元方法

訪問一個table的字段時形娇,如果table有這個字段,直接返回對應(yīng)的值筹误;
當(dāng)table沒有這個字段桐早,就會去找table的元表的__index,沒有找到返回nil。
如果有的話分兩種情況厨剪,__index可以是方法也可以是一個table哄酝。

如果是一個方法,會將table和key傳入調(diào)用此方法祷膳,結(jié)果如下

local m = {
    __index = function(table, key)
        return key .. key
    end
}

local t = {}
setmetatable(t, m)
// 這時 t.a == 'aa', t.abc == 'abcabc'

如果是一個table,就會去找這個table對應(yīng)的key,找到則返回陶衅,沒找到則會繼續(xù)找這個table的元表的__index,也就是說會一直向上尋找直晨。

local a = {}
local b = {a = 1}
local c = {b = 2}
setmetatable(a, {__index = b})
setmetatable(b, {__index = c})
// a.a == 1
// a.b == 2

__newindex元方法

這個方法是在更新table的key時調(diào)用搀军,也就是給table的key賦值時。主要的作用在于可以

local a = {}
setmetatable(a, {
    __newindex = function(table, key, value) 
    print(key)
    print(value)
    end
})
a.a = 10
// 會打印出 a 10

面向?qū)ο?/h2>

有了上面元表的基礎(chǔ)勇皇,我們就可以實現(xiàn)lua的面向?qū)ο罅苏志洹N覀兌x一個table作為類,當(dāng)我們創(chuàng)建對象時敛摘,將這個類作為元方法中的__index,再使用lua中的self關(guān)鍵字

local People = {
    name = ''
}

function People:say()
    print(self.name)
end

function People:new(name)
    local o = {name = name}
    setmetatable(o, {__index = self})
    
    return o
end

local xiaoming = People:new('xiaoming')
xiaoming:say() // 打印出 xiaoming

下面是繼承

local People = {
    name = ''
}

function People:say()
    print(self.name)
end

function People:new(name)
    local o = {name = name}
    setmetatable(o, {__index = self})

    return o
end

local Teacher = {
}
function Teacher:say()
    print('teacher ' .. self.name)
end
setmetatable(Teacher, {__index = People})

local xiaoming = Teacher:new('xiaoming')
xiaoming:say() // 打印出 teacher xiaoming

當(dāng)然门烂,實現(xiàn)類與對象和繼承的方式還有其他的很多種,上面只是示范其中的原理着撩。我們可以封裝一個 class 方法诅福,用來定義類并可以傳入父類,更方便地實現(xiàn)面向?qū)ο笸闲稹_@里就不詳述了氓润。直接搜索相關(guān)關(guān)鍵字就好。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者

  • 序言:七十年代末薯鳍,一起剝皮案震驚了整個濱河市咖气,隨后出現(xiàn)的幾起案子挨措,更是在濱河造成了極大的恐慌,老刑警劉巖崩溪,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件浅役,死亡現(xiàn)場離奇詭異,居然都是意外死亡伶唯,警方通過查閱死者的電腦和手機觉既,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來乳幸,“玉大人瞪讼,你說我怎么就攤上這事〈舛希” “怎么了符欠?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長瓶埋。 經(jīng)常有香客問我希柿,道長,這世上最難降的妖魔是什么养筒? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任曾撤,我火速辦了婚禮,結(jié)果婚禮上闽颇,老公的妹妹穿的比我還像新娘盾戴。我一直安慰自己,他們只是感情好兵多,可當(dāng)我...
    茶點故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布尖啡。 她就那樣靜靜地躺著,像睡著了一般剩膘。 火紅的嫁衣襯著肌膚如雪衅斩。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天怠褐,我揣著相機與錄音畏梆,去河邊找鬼。 笑死奈懒,一個胖子當(dāng)著我的面吹牛奠涌,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播磷杏,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼溜畅,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了极祸?” 一聲冷哼從身側(cè)響起慈格,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤怠晴,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后浴捆,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蒜田,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年选泻,在試婚紗的時候發(fā)現(xiàn)自己被綠了冲粤。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡滔金,死狀恐怖色解,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情餐茵,我是刑警寧澤,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布述吸,位于F島的核電站忿族,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏蝌矛。R本人自食惡果不足惜道批,卻給世界環(huán)境...
    茶點故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望入撒。 院中可真熱鬧隆豹,春花似錦、人聲如沸茅逮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽献雅。三九已至碉考,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間挺身,已是汗流浹背侯谁。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留章钾,地道東北人墙贱。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像贱傀,于是被迫代替她去往敵國和親惨撇。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,792評論 2 345

推薦閱讀更多精彩內(nèi)容