go語言沒有指針嗎 go語言沒有指針嗎怎么寫

為什么許多原本的 Java 項目都試圖用 go 進行重寫開源?

項目推倒重構是項目開發(fā)大忌,一方面我們要盡量避免做項目推倒重構,盡量在前期就規(guī)劃好,另一方面,我們又希望項目能常做小重構,這對項目可持續(xù)性開發(fā)是很有幫助的。而語言的重構,把Java項目用Go語言重寫一遍,無疑是一次重大的推倒重來。

成都創(chuàng)新互聯公司是一家專業(yè)提供扶風企業(yè)網站建設,專注與網站建設、做網站、H5響應式網站、小程序制作等業(yè)務。10年已為扶風眾多企業(yè)、政府機構等服務。創(chuàng)新互聯專業(yè)的建站公司優(yōu)惠進行中。

一、Go語言的優(yōu)勢在哪里

Go語言領先于Java的最大優(yōu)勢,就在于快。Go語言會被編譯成機器代碼,直接執(zhí)行;Java語言則使用JVM運行其代碼,這比Go語言要慢了很多。另外,Java語言的內存管理,相比于Go語言,也復雜得多,而內存管理,不管對于程序運行,還是對程序員的開發(fā),都極為重要。最后,Go語言沒有引用只有指針,這比Java語言處處引用,又領先了一個身位。

二、Go語言為什么更適合開源

開源,也就是開放源代碼,最大的好處在于,可以利用全世界的程序員資源,來幫助你完善你的產品,開發(fā)新需求,或者修復產品BUG。這對產品的可持續(xù)發(fā)展,是非常有幫助的,很多企業(yè)紛紛將自己的產品開源,其實就是這個道理。而Go語言更易學,更易避錯,更易閱讀等特點,就決定了它更適合用來做開源項目。

三、Java語言的優(yōu)勢

Java語言是目前軟件開發(fā)中使用率最廣泛,也是最重要的程序之一,它的地位,絕對不是目前Go語言可以比擬的。Java在WEB應用的開發(fā)中,有著很重要的地位。但是,Java語言相對復雜的并發(fā)設計,相當龐大的項目體系,使其在開發(fā)、測試階段都略為復雜,在某些方面已經逐步落后于其他語言。

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

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

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

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

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

Go 語言中 map 是基于 數組和鏈表 的數據結構實現的,通過 優(yōu)化的拉鏈法 解決哈希沖突,每個 bucket 可以保存 8 對鍵值,在 8 個鍵值對數據后面有一個 overflow 指針,因為桶中最多只能裝 8 個鍵值對,如果有多余的鍵值對落到了當前桶,那么就需要再構建一個桶(稱為溢出桶),通過 overflow 指針鏈接起來。

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

無腦機翻如下:

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

將“ allOverflow [] unsafe.Pointer”添加到 hmap 并將所有溢出存儲桶存儲在其中。 然后將 bmap 標記為noScan。 這將使掃描非??欤驗槲覀儾粫呙枞魏斡脩魯祿?。

實際上,它將有些復雜,因為我們需要從allOverflow中刪除舊的溢出桶。 而且它還會增加 hmap 的大小,因此也可能需要重新整理數據。

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

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

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

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

GO 一文搞懂指針和地址值的區(qū)別

go語言中的指針和地址值,在使用上常常具有迷惑性,主要是其特殊的*、符號的使用,可能會讓你摸不透,本文希望能講清楚go語言的指針(pointer)和值(value)。

這里先簡單的對指針和地址值概念做一個定義:

這是因為go方法傳遞參數的方式導致的,go方法函數傳遞參數傳遞的是一個拷貝,看看下面的程序會輸出什么?

答案是8,而不是9,因為AddAge函數修改的是學生的一個備份,而不是原始的學生對象

如果你想正確的給學生年齡增加的話,函數傳遞的需要是這個值的指針,如下所示:

需要注意的是,這里我們的指針傳遞的仍然是一個拷貝,比如,如果你將s賦值給另外一個指針地址,不會影響原有的指針,這點可以自行實踐下。

那在使用go語言開發(fā)的時候,何時該用指針何時改用地址值呢?比如考慮以下場景:

簡單原則: 當你不確定該使用哪種的時候,優(yōu)先使用指針

如果考慮在數組、切片、map等復合對象中使用指針和值,比如:

很多開發(fā)者會認為b會更高效,但是被傳遞的都是一個切片的拷貝,切片本身就是一個引用,所以這里被傳遞的其實沒有什么區(qū)別。

對于指針和地址值的使用,大家需要牢記的一點就是go數據傳遞的不可變性,活學活用此特點,在無狀態(tài)函數中此特性非常有用。

golang 方法返回的結構體為什么取不到地址?

golang方法(method)返回值提取結構體(struct)取不到地址的原因是,①返回值并沒有保存到變量中,返回值本身只是臨時保存在程序運行的堆棧的某個不確定位置,不能取地址;②實參取地址用的操作符是是,而形參聲明變量類型為指針,需要地址值用的才是*;③聲明形參為指針的參數的實參只能為地址值。

故先把修改后的代碼列出,修改要點是把“*NewPerson1().Speak()”改為“var b=NewPerson1();(b).Speak()”,同時把“NewPerson2().Speak()”改成“var a=NewPerson2();(a).Speak()”,代碼列出如下:

package main;

import "fmt";

type PersonA struct{

name string

}

func (p *PersonA) Speak () {

fmt.Println ( "person speak" ,p.name)

}

func (p PersonA) Walk ( ){

fmt . Println ( "person walk",p.name)}

func NewPerson1()(p PersonA){

return PersonA{"new Person1"}}

func NewPerson2()(p PersonA){

return PersonA{"new Person2"}}

func main () {

var a=NewPerson2 (); (a).Speak ();?

a .Walk ();

fmt. Println ("--------------------")?;

var b=NewPerson1 ();(b).Speak ();

b.Walk ()}

go代碼調試效果

關于指針變量的使用這一點go語言和其他有指針的程序語言如c語言是一樣的,從來只有返回值為地址/指針,而從沒有在賦值前給返回值取地址這種運算,類似的錯誤晚點再整理。

不一樣的是,go語言更簡單go語言函數可以使用結構體或者結構體的指針(pointer)以傳遞結構體參數,而且和c語言不一樣的是,go語言沒有區(qū)分結構體指針和結構體訪問成員的運算符,go語言只有“.”適用于兩種情況,而沒有c語言為結構體指針專門準備的“-”運算符。

可以使用結構體指針,作為結構體的方法的參數以指代自身嗎,

網頁名稱:go語言沒有指針嗎 go語言沒有指針嗎怎么寫
網頁鏈接:http://www.bm7419.com/article28/ddehpjp.html

成都網站建設公司_創(chuàng)新互聯,為您提供做網站云服務器、網站建設、品牌網站設計、App開發(fā)、建站公司

廣告

聲明:本網站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯

成都定制網站網頁設計