日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

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

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
在什么情況下使用Go指針

在什么情況下使用Go指針,針對這個問題,這篇文章詳細介紹了相對應(yīng)的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

公司主營業(yè)務(wù):成都網(wǎng)站建設(shè)、做網(wǎng)站、移動網(wǎng)站開發(fā)等業(yè)務(wù)。幫助企業(yè)客戶真正實現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競爭能力。成都創(chuàng)新互聯(lián)是一支青春激揚、勤奮敬業(yè)、活力青春激揚、勤奮敬業(yè)、活力澎湃、和諧高效的團隊。公司秉承以“開放、自由、嚴謹、自律”為核心的企業(yè)文化,感謝他們對我們的高要求,感謝他們從不同領(lǐng)域給我們帶來的挑戰(zhàn),讓我們激情的團隊有機會用頭腦與智慧不斷的給客戶帶來驚喜。成都創(chuàng)新互聯(lián)推出湘陰免費做網(wǎng)站回饋大家。

                           

在什么情況下使用Go指針

Go 代碼中使用指針對于新手來說不太友好,尤其有時很難區(qū)分使用場景。

我認為使用指針時最大的誤解之一就是覺得 Go 中指針和 C 語言中的指針非常像。然而,事情并非如此。指針在 Go 中不像它們在 C/C++ 中那樣工作。

本文將一起探討如何正確使用 Go 指針(Go Pointer)。

錯誤結(jié)論:使用指針性能更優(yōu)?

普遍認為當(dāng)使用指針時,應(yīng)用將會運行的更快,因為這將避免一直進行值復(fù)制。在 Go 中我們有同樣的想法也就不足為奇了。

然而,Go 中指針傳遞通常都比值傳遞慢。這是 Go 是具有垃圾回收機制語言的一個結(jié)果。當(dāng)你向一個函數(shù)傳遞指針, Go 需要執(zhí)行逃逸分析來確定變量是應(yīng)該存儲在堆中,還是棧中。 這已經(jīng)增加了一些額外的開銷,但除此之外變量可以存儲在堆中。當(dāng)你在堆中存儲一個變量,你也就在 GC 執(zhí)行時損失了時間。

Go 的一個便捷的功能是你可以通過執(zhí)行命令 go build -gcflags="-m" 來檢查逃逸分析做了什么。如果你這樣做,Go 將告訴你一個變量是否逃到堆上:

./main.go:44:20: greet ... argument does not escape
./main.go:44:21: greeting escapes to heap
./main.go:44:21: name escapes to heap

如果一個變量沒有逃逸到堆中,它就在棧中。棧是不需要垃圾回收器來清除變量的,它只做 push/pop 操作。

如果任何內(nèi)容都進行值傳遞,那么將一直在棧中做相關(guān)處理,這不會帶來垃圾回收方面的開銷。(GC 將按默認設(shè)置運行。堆中內(nèi)容越少使得 GC 需要做的事情也越少)。

現(xiàn)在你知道了吧,使用指針反而會降低性能,那么什么時候需要使用指針呢?

拷貝大的數(shù)據(jù)結(jié)構(gòu)

指針是否一直表現(xiàn)的比值傳遞差呢?顯然不是這樣的。對大的數(shù)據(jù)結(jié)構(gòu)進行處理時,指針將發(fā)揮作用。這樣可能會使得垃圾回收的開銷被拷貝大量數(shù)據(jù)的開銷抵消掉。

當(dāng)我提到這點時,總是被問到‘那個大數(shù)據(jù)應(yīng)該多大’?

我覺得這里沒有一個固定的數(shù)值,凡是與性能相關(guān)的,都應(yīng)該對其進行基準測試。 Go 有內(nèi)置的強大的基準測試工具,完全可以利用起來

可變性

唯一能修改函數(shù)參數(shù)的方式是傳指針。默認對值的修改都是在副本上進行的。因此這些修改不能在調(diào)用它的函數(shù)中體現(xiàn)。

看下面的代碼:

type person struct {
 name string
}func main() {
 p := person{"Richard"}
 rename(p)
 fmt.Println(p)
}func rename(p person) {
 p.name = "test"
}

輸出是 Richard ,因為對 person 的修改是在它的副本上進行的。如果要改變底層 person 對象的值,需要使用指針。

func main() {
 p := person{"Richard"}
 rename(&p)
 fmt.Println(p)
}func rename(p *person) {
 p.name = "test"
}

如上,輸出 test ??勺冃允侵羔樤?Go 中使用的一種情景。這是否是好事,還需要討論。

API 一致性

使用指針可以維持最新值。這可以保持 API 一致性,即使不是所有的方法都改變它的值。

因此,這個:

func (p *person) rename(s string) {
   p.name = s 
}func (p *person) printName() {
  fmt.Println(p.name)
}

優(yōu)于

func (p *person) rename(s string) {
   p.name = s 
}func (p person) printName() {
  fmt.Println(p.name)
}

雖然為了一致性并不需要在 printName 中使用指針。但是這將使得 API 更簡單,避免去記到底哪里需要引用。

表示缺失

一般值在使用時,具有默認零值。但有些情景需要知道某個事物是缺少或未填充值。例如一個結(jié)構(gòu)體包含學(xué)生的考試分數(shù),如果結(jié)構(gòu)體是空且有分數(shù) 0 ,這表示這個學(xué)生考的不好,還是壓根沒有參加考試呢?

指針的默認零值是 nil 指針,表示沒有設(shè)置值。也可以像下面這樣實現(xiàn)這種要求:

type exam struct {
    score   int
    present bool
}

使用單獨的 present 字段表示學(xué)生沒有參加考試。

為什么我選擇值?

這多少會有些主觀意識在里面。不同的人對編程有不同的理解,所以不要求大家觀念一致

我相信讓 Go 中值盡量有默認值是有意義的。這也許不適用所有的場景,但在我開來這可以避免造成一個大的事故。使用值替代指針不會因空指針造成 Tony Hoare 的 “百萬美元失誤”。

默認零值是很有用的,可以避免大量的聲明。

另一個好處是易變性造成的問題比它解決的問題多的得多。易變性給函數(shù)帶來的副作用同時使得調(diào)試變得更加困難。 通過讓函數(shù)返回修改之后的結(jié)構(gòu)體,可以避免這種突變。

重寫之前的例子

func main() {
 p := person{"richard"}
 p = rename(p)
 fmt.Println(p)
}func rename(p person) person {
 p.name = "test"
 return p
}

這也是 append 如何工作的,所以并不陌生。

x := []int{1,2}
x = append(x, 3)
x = append(x, 4)

鑒于指針的安全性,和值處理比指針處理更快,使用指針需要反復(fù)斟酌。

關(guān)于在什么情況下使用Go指針問題的解答就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道了解更多相關(guān)知識。


網(wǎng)站欄目:在什么情況下使用Go指針
本文來源:http://www.dlmjj.cn/article/ppdgij.html