最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

Lua 元表與元方法

2021-02-03 22:42 作者:多華宮與火火里  | 我要投稿

一點點講,娓娓道來。

因為不那么好理解,至少不像1+1=2那樣容易理解。

比如現(xiàn)在建立一個表xx={23}然后顯然這個表里只有一個元素,那么如果你想要xx[2]這個東西,你就會發(fā)現(xiàn)這東西當然不存在,即為nil,你只能用xx[1]這個表中唯一的東西,還有當然這個xx[1]等于23

然后呢,lua中有個東西名叫元表,元表是什么呢,首先元表是個表,其次這個表能改變其它別的表的“行為”。好像很奇怪,舉個例子,比如有兩個表,一個xx={23}一個oo={66},這兩個表各是各的,你當然也沒辦法說把兩個表乘起來或者加起來,或者也沒辦法使用一個你原來表里就沒有的元素,而現(xiàn)在,為了對兩個table進行操作,lua中為你準備了“元表”這么一個東西

再來剛剛的,我們建立一個表xx={23},然后我們再建立一個表,當然表名字隨便,比如建個表kkm40={},然后呢,我們可以設置這兩個表的關系,讓它們有點關系,我們設置kkm40為xx的元表,設置元表首先一定要用到setmetatable函數(shù),這個函數(shù)是lua里的函數(shù)(就像lua里有math.random函數(shù)一樣),這個setmetatable函數(shù)一共有兩個參數(shù),你要填兩個表,它的作用就是,設定后一個表是前一個表的元表,比如你現(xiàn)在setmetatable(xx,kkm40)的話就表示你設定xx這個表的元表是kkm40,那么具體啥是元表呢,你可以把“元表”理解為一個“背后的支持者”,沒錯,kkm40就是xx背后的支持者!那么它要怎么支持呢?比如像剛剛你想用xx[2]的時候,誒,沒有這個東西,那此時你背后的支持者——元表kkm40就可以幫助你,為你提供比如xx[2]這個東西,但是先莫要慌,因為現(xiàn)在kkm40這個表還是個空表,對吧,剛剛建立的是kkm40={},空的肯定沒啥用,你要成為背后的支持者,那么還需要為kkm40這個“元表”里面設定一些“元方法”,這些元方法就可以來支持xx表了。那就來設置元方法吧,在kkm40表里再設定一個表,像這樣

kkm40={__index={[2]=666}}

這樣就設定了一個元方法,那么此時你用setmetatable(xx,kkm40)的話,就和剛剛當然不一樣了,然后這樣設置好元表以后,你就可以用print打印出xx[2]了,你就能得到666而不會像一開始那樣得到nil,文字描述了這些以后,當然目前所形容的代碼如下

xx={23}

kkm40={__index={[2]=666}}

setmetatable(xx,kkm40)

print(xx[2])

打印結果當然是666了

然后,繼續(xù)解釋,首先是,這個設置元方法啊,那個“語法”是固定的,比如我剛剛用到的__index這個東西不是我隨便取名字取的,如果是固定語法我就會特意強調(diào)的,比如我說一個表的名字可以隨便取,就像我取名kkm40一樣,但是也有不能自由發(fā)揮的地方,那就是固定語法,比如for就是固定語法,你當然不能用fffor來實現(xiàn)for循環(huán)了,對吧,這里的__index也一樣是固定語法,需要記清楚,這個__index中有兩個下劃線,不是_而是__? ? ??

再然后,index也是死的,不是我隨便取名的,所以這個__index就和for一樣是死的,不要用fooooor來循環(huán)哦!

然后,現(xiàn)在不是能print出xx[2]了嗎,需要注意的是,你設置元表,至少是沒有改變你原來的表的,也就是說你的xx這個表其實還是原來的{23}這個樣子,而不是{23,666},那么為什么現(xiàn)在卻能print出xx[2]呢,因為在你設置好元表以后,如果你要訪問表里的某個東西,那么首先會在你原來的表里查找,看你原來的表里有沒有這個東西,如果沒有就會到你這個表的元表里查找有沒有這個東西,如果有的話,你當然就能訪問到,如果元表里都還沒有的話,就會訪問不到了,你就訪問的是nil了。所以剛剛的過程是這樣的:

建一個xx={23}然后建立表kkm40={__index={[2]=666}},用setmetatable函數(shù)設定kkm40為xx的元表,然后我們print打印xx[2],那就開始找,在xx表里發(fā)現(xiàn)沒有xx[2],因為xx是等于{23}這個的,那么開始往元表kkm40里看,看kkm40里有沒有設定元方法,發(fā)現(xiàn)誒有元方法,看看里面能不能找到相應的鍵,發(fā)現(xiàn)里面有[2]這個東西,所以kkm40這個背后的支持者就讓你成功的打印出了xx[2],但是這不代表你xx這個原來的表有任何改變,你xx還是等于{23}的。所以需要記住,在設置了元表以后,如果元表里有__index這個元方法的話,那么當你訪問原來的table里的元素的時候,如果里面找不到相應的鍵,就會到你元表中的這個__index元方法里面查找有沒有,有就可以訪問到。(注意一點啊,你這么設定了元表以后,如果原table里找不到它就一定會在元表里面找一找有沒有,如果你設定了元表又不想它到元表里找一找的話,就涉及到一些其它的知識點了,這先不講太多,并不是本次所講的重點。只需記住,你像這樣設定了元表,那么你原來table里沒有這個東西的話,它就一定一定一定會再跑到你的元表里找一找、看一看有沒有)

所以根據(jù)以上所講,顯然在你設置了元表的時候,如果你在原來表里能訪問到某元素的話,它就不會到元表里找了,只有在訪問不到的時候才會堅決地去元表里面找一找,所以如果是比如如下這種代碼的話,它就會print出23而不是666

xx={23}

kkm40={__index={[1]=666}}

setmetatable(xx,kkm40)

print(xx[1])

原因很簡單,就是你原來的xx表里有xx[1]所以就直接訪問了,它就不會去看你的元表,所以結果不會是你元表中設定的[1]=666,而是xx[1]就等于23了

然后,另外,剛剛這個__index設定的它是一個表嘛,設的是__index={[2]=666}

但是你其實還可以設定成函數(shù),比如你設定__index=function(tbl,aaaaa) if aaaaa==2 then return 666 end end? 這樣和剛剛的效果是一樣的,比如你設定了kkm40為xx的元表,那么你在這元方法里用的這函數(shù)的參數(shù)會自動給你傳入,第一個參數(shù)就自動是你原來的表,即xx,第二個參數(shù)就自動指的相應的“鍵”,參數(shù)名字當然都是隨便的,比如這里取的tbl和aaaaa,所以像是如下的代碼,就和前面提到的另一種寫法是等價的

xx={23}

kkm40={

__index=function(tbl,kkk)

if kkk==2 then

return 666

end

end

}

setmetatable(xx,kkm40)

print(xx[2])

一樣會print出xx[2]為666

所以同理比如,以下代碼

xx={23}

kkm40={

__index=function(tbl,kkk)

if kkk=="ccc" then

return 666

end

end

}

setmetatable(xx,kkm40)

print(xx.ccc)

也是同樣道理,xx表里原來沒有“ccc”這個下標,那么就在元表里找找看,在元表里有__index這個元方法,那么好,看看里面有沒有"ccc"這個下標,發(fā)現(xiàn)有,所以成功print出了xx.ccc

好了,剛剛費了這么大勁講了__index這個固定的元方法,那然后呢,實際上還有更多的元方法供你使用,當然同樣的這些元方法都是固定的,就像__index的固定語法一樣??!

下面介紹__add這個元方法,這個元方法呢,可以讓你自定義兩個table的“加法”運算,比如本來你有兩個表,一個xx一個oo,這兩個表之間當然沒辦法相加了,但是在有了__add以后,你就可以用出xx+oo這種東西了。

那么來更詳細地舉例,首先建立一個表xx={23,5,7}然后還建一個表oo={66,-1,2}

現(xiàn)在希望定義運算xx+oo,那么就要用到元表,所以顯然我們還需要建立一個表,并將這個表作為xx或oo其中一個的元表,然后還要用到固定語法__add才能使用+加法運算,所以我們再建一個表kkm40={},當然這里面應該有元方法__add,因為我們這里要定義加法運算到底是哪種規(guī)則的,所以我們要自定義一個函數(shù),所以我們設kkm40這個表為下面這樣

kkm40={

__add=function(tbl,tbl2)

for i=1,#tbl do

tbl[i]=tbl[i]+tbl2[i]

end

return tbl

end

}

看不太舒服的話,那就如圖,看如下圖片

這樣我們就設定了__add元方法,我們設定一個自定義函數(shù),函數(shù)兩個參數(shù)名字當然隨便取,然后這里同樣的,在后面設定好元表以后,用到該元方法時,會自動給函數(shù)提供那兩個參數(shù),比如你要運算xx+oo那么函數(shù)參數(shù)就自動填入的是:第一個填xx第二個填oo,反過來的話,如果你要運算oo+xx的話,那么函數(shù)自動第一個參數(shù)就是oo第二個參數(shù)就是xx,好,那你看這個函數(shù)怎么定義的呢,for循環(huán)遍歷tbl表,然后讓tbl[i]等于tbl[i]加上tbl2[i],然后最后返回tbl(不要忘記返回tbl喲?。?/span>,這樣的話,我們就規(guī)定好這個元方法了,顯然這個元方法的規(guī)則就是讓兩個table的元素都一一對著加起來,這樣就是+加法運算了,當然你也可以設定不同的規(guī)則了,反正這個自定義函數(shù)你可以自由發(fā)揮嘛。

然后再建立好這個kkm40表以后,當然為了設置元表,我們用上setmetatable函數(shù),就這樣setmetatable(xx,kkm40)就是給xx設定一個元表kkm40

在設置好元表以后,當然,你就可以用比如xx+oo這種兩個表之間的“加法”運算了,總的來說代碼如下

xx={23,5,7} ? oo={66,-1,2}

kkm40={

__add=function(tbl,tbl2)

for i=1,#tbl do

tbl[i]=tbl[i]+tbl2[i]

end

return tbl

end

}

setmetatable(xx,kkm40)

abc=xx+oo

for i=1,#abc do

print(abc[i])

end


這樣看不太清楚的話,可以看圖,圖片如下

這樣的話,abc就等于xx這個表加oo這個表了,而由于設定了元表和元方法__add,所以+加法運算才能成功執(zhí)行,那么顯然現(xiàn)在abc就會等于{89,4,9}這么一個表了,里面的數(shù)字也就是xx的每個元素分別和oo的每個元素加起來了

所以說,如果你想用+對兩個table運算,那么就一定要用元表和__add元方法。

那么剛剛說了,自定義函數(shù)你可以隨便設定,所以你也可以設定成別的"規(guī)則",比如你建的kkm40這個表是下面這樣的

kkm40={

__add=function(tbl,tbl2)

for i=1,#tbl do

table.insert(tbl,#tbl+1,tbl2[i])

end

return tbl

end

}

這樣看不清楚的話,可以看如下圖片

在tbl表最后面的位置一個個的插入tbl2的元素

這樣的話,總共的代碼就是如下這樣

那么現(xiàn)在這個abc等于xx+oo這個運算以后,顯然abc就和剛剛不一樣了,現(xiàn)在元方法里的自定義函數(shù)和剛剛不同了,現(xiàn)在的操作是在第一個table的最后的位置一個個插入另一個table的元素,所以現(xiàn)在得到的abc結果就會是{23,5,7,66,-1,2}了,不再是剛剛的{89,4,9}了,就是因為這自定義的+“加法”規(guī)則改變了,你也可以定義別的各種各樣的規(guī)則。

好,我們現(xiàn)在講了__add元方法,知道了你如果要用兩個表來+的話,就必須用元表和__add元方法,那么實際上,除了之前講的__index和__add元方法以外,還有別的元方法供你使用,當然也都是固定語法了。下面,快速列舉一些和__add使用方法相同的元方法

__sub對應的運算符 -

也就是你可以像剛剛用xx+oo那樣,你也可以自定義xx-oo是什么規(guī)則

__mul對應的運算符 *

也就是你可以像剛剛用xx+oo那樣,你也可以自定義xx*oo是什么規(guī)

__div對應的運算符 /

也就是你可以像剛剛用xx+oo那樣,你也可以自定義xx/oo是什么規(guī)則

__pow對應的運算符 ^

也就是你可以像剛剛用xx+oo那樣,你也可以自定義xx^oo是什么規(guī)則

__mod對應的運算符 %

也就是你可以像剛剛用xx+oo那樣,你也可以自定義xx%oo是什么規(guī)則

__concat對應的運算符 ..

也就是你可以像剛剛用xx+oo那樣,你也可以自定義xx..oo是什么規(guī)則









Lua 元表與元方法的評論 (共 條)

分享到微博請遵守國家法律
凉城县| 白山市| 会同县| 南皮县| 峨山| 河北省| 鄂尔多斯市| 盖州市| 札达县| 永定县| 宜川县| 云霄县| 新巴尔虎左旗| 凤庆县| 定兴县| 南乐县| 夏河县| 高碑店市| 公主岭市| 汪清县| 锦州市| 佛坪县| 时尚| 西峡县| 开平市| 石柱| 甘谷县| 郧西县| 化隆| 沙雅县| 丰台区| 离岛区| 长垣县| 田阳县| 游戏| 瓮安县| 两当县| 临潭县| 陕西省| 珠海市| 巨野县|