第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機(jī)立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

lua中table的__index對于自身有什么作用?

lua中table的__index對于自身有什么作用?

胡說叔叔 2019-03-30 11:37:08
學(xué)lua的時候一直有一個疑問就是關(guān)于table.__index比如說以下代碼:lualocala={}在沒有設(shè)置metatable的情況下,對于a來說,a.__index有什么用?還有個問題如下:lualocala={}setmetatable(a,a)a.__index=a這個代碼除了能夠讓a訪問不存在的字段時報錯,還有其他什么作用么?
查看完整描述

2 回答

?
月關(guān)寶盒

TA貢獻(xiàn)1772條經(jīng)驗(yàn) 獲得超5個贊

首先在lua里,metatable是一個很神奇的東西,感覺題主把metatable和__index混淆了。
在lua里,每一種數(shù)據(jù)類型都可以擁有metatable,不光是table這種類型。只不過table的metatable你可以通過lua暴露出來的腳本接口修改,也就是setmetable來設(shè)置,而其他的lua數(shù)據(jù)類型的metatable你無法通過腳本修改,要修改只能修改c源碼然后重新編譯,同時,在lua里,除了table和userdata外,其他的所有類型數(shù)據(jù)都是一種類型共享同一個metatable的,比如所有字符串的metatable都是同一個。
然后再來說metatable有什么用?參考lua5.1的實(shí)現(xiàn),metatable跟一般的luatable沒什么區(qū)別,也是k-v對。你可以通過修改metatable的部分特殊的key對應(yīng)的value內(nèi)容,來達(dá)到修改這種數(shù)據(jù)一些默認(rèn)操作的目的,如果你寫過C++應(yīng)該就能明白,它有點(diǎn)像C++里的操作符重載,比如把+號重載成兩個數(shù)相乘這種做法。當(dāng)然,lua里的metatable都涉及到哪些方面呢?也就是你可以修改什么東東呢?
算術(shù)運(yùn)算、比較操作、級聯(lián)操作、取長度操作、索引操作,除此之外還可以設(shè)置當(dāng)userdata被垃圾回收器回收時調(diào)用一個指定函數(shù)這種操作。
每當(dāng)對lua中的一個數(shù)據(jù)進(jìn)行上面這些操作時,就會觸發(fā)一個對應(yīng)的事件,然后lua虛擬機(jī)就會查找這個數(shù)據(jù)有沒有metatable,以及metatable里有沒有事件對應(yīng)的k-v存在,如果有就調(diào)用,沒有就按默認(rèn)的。
而在metatable里,事件是怎么和k-v對應(yīng)起來的呢?通過k這個字符串來對應(yīng)的。所有有效的k都是兩個下劃線開頭的字符串,有如下這些:
__add、__sub、__mul、__div
__mod、__pow
__unm
__concat
__len
__eq、__lt、__le
__index、__newindex
__call
至于他們各自代表什么意思,可以直接去看lua官網(wǎng)的文檔:鏈接描述
然后再來回答題主的疑問:
1、在沒有設(shè)置metatable的情況下,對于a來說,a.__index有什么用?
a.__index只能理解成a['__index'],理由如上,__index即使有用,也不是a的k,而應(yīng)該是a的metatable的k。
2、首先解釋一下為什么題主這么寫會報錯,而不是我們通常見到的打印一個table不存在的key值的時候直接給nil。
當(dāng)你訪問table的元素時,也就是當(dāng)你這么寫:a1時,其實(shí)觸發(fā)了index事件,然后我們在lua的文檔里可以看到觸發(fā)此事件時是如何處理的:
functiongettable_event(table,key)
localh
iftype(table)=="table"then
localv=rawget(table,key)
ifv~=nilthenreturnvend
h=metatable(table).__index
ifh==nilthenreturnnilend
else
h=metatable(table).__index
ifh==nilthen
error(···)
end
end
iftype(h)=="function"then
return(h(table,key))--callthehandler
elsereturnh[key]--orrepeatoperationonit
end
end
根據(jù)上面的代碼,我們可以看到,題主把a(bǔ)的metatable設(shè)置成a了,然后還設(shè)置了a的__index,那么有人要問了,這個__index到底是設(shè)置的a的metatable的還是a本身的呢?事實(shí)上都設(shè)置了,因?yàn)閍的metatable就是它自己。所以才會出現(xiàn)報錯的情況。按照邏輯看上面的代碼實(shí)現(xiàn),注意h=metatable(table).__index這一行,按照現(xiàn)在a的情況,那么這里h的值就應(yīng)該是a自身,然后跳到函數(shù)最后發(fā)現(xiàn)它return的還是h[key],意思是重復(fù)這個索引操作,看那行的注釋也知道,這里h是a,那么相當(dāng)于又弄一次a1的流程,結(jié)果就死循環(huán)了,這是題主所謂的訪問不存在字段時報錯的含義。至于題主說這么弄有什么作用。在我看來,你在純瞎搞。:)
                            
查看完整回答
反對 回復(fù) 2019-03-30
  • 2 回答
  • 0 關(guān)注
  • 340 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號