最近2018中文字幕在日韩欧美国产成人片_国产日韩精品一区二区在线_在线观看成年美女黄网色视频_国产精品一区三区五区_国产精彩刺激乱对白_看黄色黄大色黄片免费_人人超碰自拍cao_国产高清av在线_亚洲精品电影av_日韩美女尤物视频网站

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
go語言存放指針,go 常用命令

golang-指針類型

tips: *號,可以指向指針類型內(nèi)存地址上的值,號,可以獲取值類型的內(nèi)存地址

成都創(chuàng)新互聯(lián)公司主營克井網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營網(wǎng)站建設(shè)方案,成都app開發(fā),克井h5小程序定制開發(fā)搭建,克井網(wǎng)站營銷推廣歡迎克井等地區(qū)企業(yè)咨詢

每一個變量都有內(nèi)存地址,可以通過變量來操作內(nèi)存地址中的值,即內(nèi)存的大小

go語言中獲取變量的內(nèi)存地址方法:通過 符號可以獲取變量的地址

定義:普通變量存儲的是對應(yīng)類型的值,這些類型就叫值類型

變量b,在內(nèi)存中的地址為:0x1040a124,在這個內(nèi)存地址上存儲的值為:156

定義:指針類型的變量存儲的是?個地址,所以?叫指針類型或引?類型

b 是值類型,它指向的是內(nèi)存地址上的值

a是指針類型,它指向的是b的內(nèi)存地址

指針類型定義,語法: var 變量名 *類型

指針類型在定義完成后,默認(rèn)為空地址,即空指針(nil)

在定義好指針變量后,可以通過***** 符號可以獲取指針變量指向的變量

在這里的 *a 等價于 b,通過修改 *a ,最終修改的是值類型b的值

這里a,d是值類型,b,c是指針類型

d就相當(dāng)于把a(bǔ)內(nèi)存地址上值,在內(nèi)存中從新開辟了一塊空間存儲,d和a互不影響

b,c相當(dāng)于指向了a的內(nèi)存地址,當(dāng)使用*號引用出內(nèi)存地址上的變量上,修改值得,a的值也會跟著改變

Go語言使用 map 時盡量不要在 big map 中保存指針

不知道你有沒有聽過這么一句:在使用 map 時盡量不要在 big map 中保存指針。好吧,你現(xiàn)在已經(jīng)聽過了:)為什么呢?原因在于 Go 語言的垃圾回收器會掃描標(biāo)記 map 中的所有元素,GC 開銷相當(dāng)大,直接GG。

這兩天在《Mastering Go》中看到 GC 這一章節(jié)里面對比 map 和 slice 在垃圾回收中的效率對比,書中只給出結(jié)論沒有說明理由,這我是不能忍的,于是有了這篇學(xué)習(xí)筆記。扯那么多,Show Your Code

這是一個簡單的測試程序,保存字符串的 map 和 保存整形的 map GC 的效率相差幾十倍,是不是有同學(xué)會說明明保存的是 string 哪有指針?這個要說到 Go 語言中 string 的底層實(shí)現(xiàn)了,源碼在 src/runtime/string.go里,可以看到 string 其實(shí)包含一個指向數(shù)據(jù)的指針和一個長度字段。注意這里的是否包含指針,包括底層的實(shí)現(xiàn)。

Go 語言的 GC 會遞歸遍歷并標(biāo)記所有可觸達(dá)的對象,標(biāo)記完成之后將所有沒有引用的對象進(jìn)行清理。掃描到指針就會往下接著尋找,一直到結(jié)束。

Go 語言中 map 是基于 數(shù)組和鏈表 的數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)的,通過 優(yōu)化的拉鏈法 解決哈希沖突,每個 bucket 可以保存 8 對鍵值,在 8 個鍵值對數(shù)據(jù)后面有一個 overflow 指針,因?yàn)橥爸凶疃嘀荒苎b 8 個鍵值對,如果有多余的鍵值對落到了當(dāng)前桶,那么就需要再構(gòu)建一個桶(稱為溢出桶),通過 overflow 指針鏈接起來。

因?yàn)?overflow 指針的緣故,所以無論 map 保存的是什么,GC 的時候就會把所有的 bmap 掃描一遍,帶來巨大的 GC 開銷。官方 issues 就有關(guān)于這個問題的討論, runtime: Large maps cause significant GC pauses #9477

無腦機(jī)翻如下:

如果我們有一個map [k] v,其中k和v都不包含指針,并且我們想提高掃描性能,則可以執(zhí)行以下操作。

將“ allOverflow [] unsafe.Pointer”添加到 hmap 并將所有溢出存儲桶存儲在其中。 然后將 bmap 標(biāo)記為noScan。 這將使掃描非??欤?yàn)槲覀儾粫呙枞魏斡脩魯?shù)據(jù)。

實(shí)際上,它將有些復(fù)雜,因?yàn)槲覀冃枰獜腶llOverflow中刪除舊的溢出桶。 而且它還會增加 hmap 的大小,因此也可能需要重新整理數(shù)據(jù)。

最終官方在 hmap 中增加了 overflow 相關(guān)字段完成了上面的優(yōu)化,這是具體的 commit 地址。

下面看下具體是如何實(shí)現(xiàn)的,源碼基于 go1.15,src/cmd/compile/internal/gc/reflect.go 中

通過注釋可以看出,如果 map 中保存的鍵值都不包含指針(通過 Haspointers 判斷),就使用一個 uintptr 類型代替 bucket 的指針用于溢出桶 overflow 字段,uintptr 類型在 GO 語言中就是個大小可以保存得下指針的整數(shù),不是指針,就相當(dāng)于實(shí)現(xiàn)了 將 bmap 標(biāo)記為 noScan, GC 的時候就不會遍歷完整個 map 了。隨著不斷的學(xué)習(xí),愈發(fā)感慨 GO 語言中很多模塊設(shè)計得太精妙了。

差不多說清楚了,能力有限,有不對的地方歡迎留言討論,源碼位置還是問的群里大佬 _

go語言怎么輸出存放指針的數(shù)組

以下代碼在VC6.0以上版本測試通過!

輸出結(jié)果:6

#include stdio.h

int main(void)

{

int a[2][2] = {{1,2}, {3,4}};

int b[2][2] = {{5,6}, {7,8}};

int (*p1)[2] = a;

int (*p2)[2] = b;

int (*q[2])[2] = {p1, p2}; 這樣才是正確的定義!

printf("%d\n", *(*q[1]+1));

return 0;

}

但在tc2.0和bc3.1中提示非法初始化!

但把

int (*q[2])[2] = {p1, p2};

改成

int (*q[2])[2];

q[0] = p1;

q[1] = p2;

可以通過!

原因暫不清楚,估計是老舊的編譯器不支持太復(fù)雜的定義!

其實(shí)最好的方法是使用typedef,簡單明了,可讀性大大提升!

#include stdio.h

int main(void)

{

typedef int (*PA)[2]; 使用typedef

int a[2][2] = {{1,2}, {3,4}};

int b[2][2] = {{5,6}, {7,8}};

int (*p1)[2] = a;

int (*p2)[2] = b;

PA q[2]= {p1, p2}; 這樣可讀性是否大大的增加?!

printf("%d\n", *(*q[1]+1));

return 0;

}


新聞標(biāo)題:go語言存放指針,go 常用命令
本文鏈接:http://fisionsoft.com.cn/article/dssogsg.html