日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

lua之弱引用table

發(fā)布時間:2024/2/28 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 lua之弱引用table 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Lua之弱引用table

核心原理:lua的弱引用不增加引用計(jì)數(shù)

這篇文章主要介紹了Lua教程之弱引用table,本文講解了自動內(nèi)存管理的缺陷、弱引用table、三種形式的弱引用等內(nèi)容,需要的朋友可以參考下

這次要介紹的內(nèi)容比較少,就一個——弱引用table

1.無法超越人類智慧的智能——自動內(nèi)存管理的缺陷

我們都知道,Lua是具備自動內(nèi)存管理的,好吧,也許有些朋友不知道。

我們只管創(chuàng)建對象,無須刪除對象(當(dāng)然,對于不要的對象你需要設(shè)置一下nil值),Lua會自動刪除那些被認(rèn)為是垃圾的對象。

問題就出現(xiàn)在,什么對象才是垃圾對象,有些時候,我們很清楚某個對象是垃圾,但是,Lua卻無法發(fā)現(xiàn)。
?
比如這樣一個例子:

t = {};-- 使用一個table作為t的key值 key1 = {name = "key1"}; t[key1] = 1; key1 = nil;-- 又使用一個table作為t的key值 key2 = {name = "key2"}; t[key2] = 1; key2 = nil;-- 強(qiáng)制進(jìn)行一次垃圾收集 collectgarbage();for key, value in pairs(t) doprint(key.name .. ":" .. value); end

這段代碼有點(diǎn)復(fù)雜,智商低于250的可能會看不懂。

首先以一個table,叫做t。

然后創(chuàng)建一個新的table——key1,這個key1作為t的key值,給t新增了一個字段,賦值為1。

同樣的,key2也作為t的一個key值。

接著,調(diào)用了collectgarbage函數(shù),可以不管它,我們只要知道,它會讓lua進(jìn)行一次垃圾回收。

最后輸出t的所有字段,輸出結(jié)果如下:

[LUA-print] key1:1 [LUA-print] key2:1

這很符合常理,也在我們的預(yù)計(jì)當(dāng)中,雖然我們在給t賦值之后,key1和key2都賦值為nil了。

但是,已經(jīng)添加到table中的key值是不會因此而被當(dāng)做垃圾的。

換句話說,key1本身已經(jīng)是nil值,但它曾經(jīng)所指向的內(nèi)容依然存放在t中。key2也是一樣的情況。

所以我們最后還是能輸出key1和key2的name字段。

2.顛覆你的認(rèn)知——弱引用table

剛剛舉例的只是正常情況,那么,如果我們把某個table作為另一個table的key值后,希望當(dāng)table設(shè)為nil值時,另一個table的那一條字段也被刪除。

應(yīng)該如何實(shí)現(xiàn)?

這時候就要用到弱引用table了,弱引用table的實(shí)現(xiàn)也是利用了元表。

我們來看看下面的代碼,和之前幾乎一樣,只是加了一句代碼:

?t = {};-- 給t設(shè)置一個元表,增加__mode元方法,賦值為“k” setmetatable(t, {__mode = "k"});-- 使用一個table作為t的key值 key1 = {name = "key1"}; t[key1] = 1; key1 = nil;-- 又使用一個table作為t的key值 key2 = {name = "key2"}; t[key2] = 1; key2 = nil;-- 強(qiáng)制進(jìn)行一次垃圾收集 collectgarbage();for key, value in pairs(t) doprint(key.name .. ":" .. value); end

留意,在t被創(chuàng)建后,立刻給它設(shè)置了元表,元表里有一個__mode字段,賦值為”k”字符串。

如果這個時候大家運(yùn)行代碼,會發(fā)現(xiàn)什么都沒有輸出,因?yàn)?#xff0c;t的所有字段都不存在了。

這就是弱引用table的其中一種,給table添加__mode元方法,如果這個元方法的值包含了字符串”k”,就代表這個table的key都是弱引用的。

一旦其他地方對于key值的引用取消了(設(shè)置為nil),那么,這個table里的這個字段也會被刪除。
?
通俗地說,因?yàn)閠的key被設(shè)置為弱引用,所以,執(zhí)行t[key1] = 1后,t中確實(shí)存在這個字段。

隨后,又執(zhí)行了key1 = nil,此時,除了t本身以外,就沒有任何地方對key1保持引用,所以t的key1字段也會被刪除。

3.三種形式的弱引用

對于弱引用table,其實(shí)有三種形式:

1)key值弱引用,也就是剛剛說到的情況,只要其他地方?jīng)]有對key值引用,那么,table自身的這個字段也會被刪除。設(shè)置方法:setmetatable(t, {__mode = “k”});
2)value值弱引用,情況類似,只要其他地方?jīng)]有對value值引用,那么,table的這個value所在的字段也會被刪除。設(shè)置方法:setmetatable(t, {__mode = “v”});
3)key和value弱引用,規(guī)則一樣,但是key和value都同時生效,任意一個起作用時都會導(dǎo)致table的字段被刪除。設(shè)置方法:setmetatable(t, {__mode = “kv”});
?
當(dāng)然,這里所說的被刪除,是指在Lua執(zhí)行垃圾回收的時候,并不一定是立刻生效的。
我們剛剛只是為了測試,而強(qiáng)制執(zhí)行了垃圾回收。

4.結(jié)束

好了,這次的內(nèi)容比較少,其實(shí)書上有蠻多關(guān)于弱引用的例子的。

關(guān)于Lua的最基礎(chǔ)部分,到這里算是結(jié)束了。

后面的內(nèi)容是一些庫的介紹,以及更深入的一些內(nèi)容(C和Lua間調(diào)用、自定義類型、線程、內(nèi)存管理)。

接下來可能會放緩文章更新速度,因?yàn)楹枚鄮斓慕榻B,不知道有沒有必要用文章記錄下來。

可能而已~

超強(qiáng)干貨來襲 云風(fēng)專訪:近40年碼齡,通宵達(dá)旦的技術(shù)人生

總結(jié)

以上是生活随笔為你收集整理的lua之弱引用table的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。