非常非常詳細(xì)的Lua面向?qū)ο螅ǘ疤?hào)蟆肆,點(diǎn)號(hào)以及self

前言

非常非常詳細(xì)的Lua面向?qū)ο螅ㄒ唬砼c元方法中說完了一些基礎(chǔ)概念拴竹,這些是我們使用Lua模擬面向?qū)ο蟮幕A(chǔ)唐础,但是在真正的實(shí)際開發(fā)中我們的代碼肯定是不能像上一篇那樣寫的箱歧,這樣可讀性太差了,而且冗余的代碼非常多一膨,每次setmetatable都看起來很長很麻煩呀邢,所以為了本篇介紹的一些語法會(huì)讓我們的代碼更加貼近實(shí)際開發(fā)的習(xí)慣。在這里我有一個(gè)建議豹绪!就是我們剛開始接觸lua中的self的時(shí)候价淌,先不要從更高更次的抽象去理解(什么這樣代表靜態(tài)方法呀,那樣代表實(shí)例方法呀瞒津,什么指向調(diào)用者自身啊之類的)蝉衣,我們還是返璞歸真,從table的角度去理解巷蚪,相信很快就能理解了病毡!

1.更簡潔的設(shè)置元表

首先先簡化上一篇文章中的setmetatable的寫法,在上一篇文章中屁柏,我們?yōu)槠胀ū砺暶饕粋€(gè)帶有__index元方法的元表是這樣寫的

_M= { __ index = { key2 = "value2" }} 
mytable = setmetatable({},_M)

emmmm啦膜,這樣寫雖然好理解,但是這樣其實(shí)是多出了一個(gè)由__index指向的匿名表淌喻。所以我們修改一下寫法

_M= {  key2 = "value2" }
mytable = setmetatable({},_M)
_M.__index=_M

看官們細(xì)品一下這兩種寫法的異同僧家,當(dāng)我們嘗試索引一個(gè)mytable普通表中沒有的key的時(shí)候,就去去索引元表的__index似嗤,發(fā)現(xiàn)__index指向的是一個(gè)table _M啸臀,所以就會(huì)繼續(xù)在_M中索引。
眾所周知烁落,Lua的table中的value值是可以指向一個(gè)function的乘粒,那現(xiàn)我們將對_M的賦值放到一個(gè)初始化方法中,這樣在我們需要用到這個(gè)表之前先調(diào)用一下這個(gè)初始化方法然后再使用伤塌,我們暫且把這個(gè)初始化方法起名叫New吧灯萍。所以代碼如下:

_M={}
mytable = setmetatable({},_M)
function _M.New()
    _M.name='my name is _M.'
    _M.age=22
    _M.__index=_M
end

然后我們只需要在打算訪問mytable之前,先調(diào)用一次_M.New()完成對表中一些值的初始化每聪,然后就可訪問了旦棉,嗯是不是有點(diǎn)我們新建對象內(nèi)味了齿风。

_M.New()
print(mytable.name) --輸出my name is _M.
print(mytable.age) --輸出22

OK,打住绑洛,我們先繼續(xù)講一講點(diǎn)號(hào)和冒號(hào)還有self

2.最普通的點(diǎn)號(hào)調(diào)用

就像上面例子中的New()方法救斑,我們最簡單自然調(diào)用它的辦法就是_M.New(),在一般情況下這樣調(diào)用一個(gè)方法已經(jīng)能達(dá)到我們的目的了真屯,比如我在一個(gè)table中添加一個(gè)很普通的輸出方法脸候,就這樣直接調(diào)用這個(gè)tableA.Print()就能達(dá)到我們輸出的效果了。

tableA = {}
function tableA.Print() 
  print('output from tableA')
end
tableA.Print()

但是如果我往tableA中添加了幾個(gè)屬性绑蔫,然后我希望在PrintA中去訪問一下這幾個(gè)屬性运沦,那我們需要怎么辦呢,也很簡單配深,就直接在方法里面顯式的聲明就好了嘛携添!

tableA = {}
--為這個(gè)table添加一個(gè)屬性
tableA.keyA='valueA'

function tableA.Print() 
  print(tableA.keyA) --輸出valueA
end
tableA.Print()

這看起來并沒有self和冒號(hào)什么事對嗎。那我們現(xiàn)在改一改上面的代碼篓叶,我新建一個(gè)表tableB然后把tableA設(shè)置為其元表烈掠。然后用tableB去調(diào)用Print()方法(不知道為什么能調(diào)用成功的同學(xué)可以去上一節(jié)看看就知道了~),依舊可以輸出valueA

tableA = {}
--為這個(gè)table添加一個(gè)屬性
tableA.keyA='valueA'
tableA.__index=tableA

function tableA.Print() 
  print(tableA.keyA) 
end

--將tableA設(shè)置為tableB元表缸托,然后調(diào)用一下Print()
tableB=setmetatable({},tableA)
tableB.Print()--輸出valueA

但是現(xiàn)在我想在tableB中也添加一個(gè)keyA(沒想到吧O虿妗),然后這次我想讓Print()打印出tableB中'keyA'的值了嗦董,這時(shí)候我們的點(diǎn)號(hào)就束手無策了。

tableA = {}
--為這個(gè)table添加一個(gè)屬性
tableA.keyA='valueA'
tableA.__index=tableA

function tableA.Print() 
  print(tableA.keyA) 
end

--將tableA設(shè)置為tableB元表瘦黑,然后調(diào)用一下Print()
tableB=setmetatable({ keyA = 'valueB' },tableA)
tableB.Print()--輸出valueA

3.self和冒號(hào)來了

想要實(shí)現(xiàn)我們上面的需求京革,self關(guān)鍵字就可以輕而易舉的達(dá)到了!我們稍微改變一下Print()的代碼幸斥。大家可以看到匹摇,我只是簡單地加入了一個(gè)名為self的參數(shù),并且把對tableA.keyA的訪問甲葬,換成了對self.keyA的訪問廊勃。

--修改前的代碼
function tableA.Print() 
  print(tableA.keyA) 
end
tableB=setmetatable({ keyA = 'valueB' },tableA)
tableB.Print()--輸出valueA

--修改后的代碼
function tableA.Print(self) 
  print(self.keyA) 
end
tableB=setmetatable({ keyA = 'valueB' },tableA)
tableB.Print(tableB)--輸出valueB

經(jīng)過這樣修改后我們再通過tableB.Print(tableB),就能夠輸出tableB.keyA的值了经窖。至此坡垫,self的作用已經(jīng)很明確了,

self代表的就是作為參數(shù)傳入的那個(gè)table

當(dāng)我們清楚了這點(diǎn)后,對于冒號(hào)調(diào)用的理解也就水到渠成了画侣,對于上面tableB.Print(tableB)這樣的寫法冰悠,如果我們想省略掉參數(shù)里的tableB,只需要改為tableB:Print()這樣就可以了

冒號(hào)調(diào)用配乱,代表默認(rèn)將調(diào)用者作為self參數(shù)溉卓,所以我們可以不用顯式的將調(diào)用者作為參數(shù)傳遞了

最后再多嘴說一種情況皮迟,加深一下對self的理解。如果現(xiàn)在我仍然想通過tableB來調(diào)用Print()桑寨,但是伏尼,我這次不想輸出tableBkeyA了,我想輸出tableA的'keyA'了嘿嘿(這嘴臉有沒有讓你們想起自己的PM或者策劃)尉尾,這也好辦爆阶,我們只需要將tableA作為self參數(shù)傳入就可以了,

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末代赁,一起剝皮案震驚了整個(gè)濱河市扰她,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌芭碍,老刑警劉巖徒役,帶你破解...
    沈念sama閱讀 218,122評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異窖壕,居然都是意外死亡忧勿,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評論 3 395
  • 文/潘曉璐 我一進(jìn)店門瞻讽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來鸳吸,“玉大人,你說我怎么就攤上這事速勇∩卫” “怎么了?”我有些...
    開封第一講書人閱讀 164,491評論 0 354
  • 文/不壞的土叔 我叫張陵烦磁,是天一觀的道長养匈。 經(jīng)常有香客問我,道長都伪,這世上最難降的妖魔是什么呕乎? 我笑而不...
    開封第一講書人閱讀 58,636評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮陨晶,結(jié)果婚禮上猬仁,老公的妹妹穿的比我還像新娘。我一直安慰自己先誉,他們只是感情好湿刽,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,676評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著谆膳,像睡著了一般叭爱。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上漱病,一...
    開封第一講書人閱讀 51,541評論 1 305
  • 那天买雾,我揣著相機(jī)與錄音把曼,去河邊找鬼。 笑死漓穿,一個(gè)胖子當(dāng)著我的面吹牛嗤军,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播晃危,決...
    沈念sama閱讀 40,292評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼叙赚,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了僚饭?” 一聲冷哼從身側(cè)響起震叮,我...
    開封第一講書人閱讀 39,211評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎鳍鸵,沒想到半個(gè)月后苇瓣,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,655評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡偿乖,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,846評論 3 336
  • 正文 我和宋清朗相戀三年击罪,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片贪薪。...
    茶點(diǎn)故事閱讀 39,965評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡媳禁,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出画切,到底是詐尸還是另有隱情竣稽,我是刑警寧澤,帶...
    沈念sama閱讀 35,684評論 5 347
  • 正文 年R本政府宣布霍弹,位于F島的核電站丧枪,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏庞萍。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,295評論 3 329
  • 文/蒙蒙 一忘闻、第九天 我趴在偏房一處隱蔽的房頂上張望钝计。 院中可真熱鬧,春花似錦齐佳、人聲如沸私恬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽本鸣。三九已至,卻和暖如春硅蹦,著一層夾襖步出監(jiān)牢的瞬間荣德,已是汗流浹背闷煤。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留涮瞻,地道東北人鲤拿。 一個(gè)月前我還...
    沈念sama閱讀 48,126評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像署咽,于是被迫代替她去往敵國和親近顷。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,914評論 2 355

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