本文由go語言教學專欄為大家介紹在什麼情況下使用Go指標(Go Pointer),希望對需要的朋友有幫助!
Go 程式碼中使用指針對新手來說較不友好,尤其有時很難區分使用情境。
我認為使用指標時最大的誤解之一就是覺得 Go 中指標和 C 語言中的指標非常像。然而,事情並非如此。指針在 Go 中不像它們在 C/C 中那樣工作。
本文將一起探討如何正確使用 Go 指標(Go Pointer)。
錯誤結論:使用指標效能更優?
普遍認為當使用指標時,應用程式將會運行的更快,因為這將避免一直進行值複製。在 Go 中我們有同樣的想法也就不足為奇了。
然而,Go 中指標傳遞通常都比值傳遞慢。這是 Go 是具有垃圾回收機制語言的一個結果。當你向函數傳遞指針, Go 需要執行逃逸分析來確定變數是應該儲存在堆中,還是堆疊中。這已經增加了一些額外的開銷,但除此之外變數可以儲存在堆中。當你在堆中儲存一個變量,你也就在 GC 執行時損失了時間。
Go 的一個方便的功能是你可以透過執行指令 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
操作。
如果任何內容都進行值傳遞,那麼將一直在堆疊中做相關處理,這不會帶來垃圾回收方面的開銷。 (GC 將按預設設定運行。堆中內容越少使得 GC 需要做的事情也越少)。
現在你知道了吧,使用指標反而會降低效能,那麼什麼時候需要使用指標呢?
拷貝大的資料結構
指標是否一直表現的比值傳遞差呢?顯然不是這樣的。當對大的資料結構進行處理時,指標就會發揮作用。這樣可能會使得垃圾回收的開銷被拷貝大量資料的開銷抵銷掉。
當我提到這一點時,總是被問到『那個大數據應該多大』?
我覺得這裡沒有一個固定的數值,凡是與效能相關的,都應該對其進行基準測試。 Go 有內建的強大的基準測試工具,完全可以利用起來
可變性
唯一能修改函數參數的方式是傳指標。預設對值的修改都是在副本上進行的。因此這些修改不能在呼叫它的函數中體現。
看下面的程式碼:
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) }
優於
func (p *person) rename(s string) { p.name = s }func (p person) printName() { fmt.Println(p.name) }
雖然為了一致性並不需要在 printName
中使用指標。但這將使得 API 更簡單,避免去記到底哪裡需要引用。
表示缺失
一般值在使用時,具有預設零值。但有些情境需要知道某個事物是缺少或未填充值。例如一個結構體包含學生的考試分數,如果結構體是空且有分數 0 ,這表示這個學生考的不好,還是壓根沒有參加考試呢?
指針的預設零值是 nil
指針,表示沒有設定值。也可以像下面這樣實現這個要求:
type exam struct { score int present bool }
使用單獨的 present
字段表示學生沒有參加考試。
為什麼我選擇值?
這多少會有些主觀意識在裡面。不同的人對程式設計有不同的理解,所以不要求大家觀念一致
我相信讓 Go 中位數盡量有預設值是有意義的。這也許不適用所有的場景,但在我開來這可以避免造成一個大的事故。使用值替代指標不會因空指標造成 Tony Hoare 的 “百萬美元失誤”。
預設零值是很有用的,可以避免大量的宣告。
另一个好处是易变性造成的问题比它解决的问题多的得多。易变性给函数带来的副作用同时使得调试变得更加困难。 通过让函数返回修改之后的结构体,可以避免这种突变。
重写之前的例子
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)
鉴于指针的安全性,和值处理比指针处理更快,使用指针需要反复斟酌。
原文地址:https://medium.com/@meeusdylan/when-to-use-pointers-in-go-44c15fe04eac
译文地址:https://learnku.com/go/t/60923
以上是你知道在啥情況下使用Go指針嗎?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

goisidealforbuildingscalablesystemsduetoitssimplicity,效率和建築物內currencysupport.1)go'scleansyntaxandaxandaxandaxandMinimalisticDesignenhanceProductivityAndRedCoductivityAndRedCuceErr.2)ItSgoroutinesAndInesAndInesAndInesAndineSandChannelsEnablenableNablenableNableNablenableFifficConcurrentscorncurrentprogragrammentworking torkermenticmminging

Initfunctionsingorunautomationbeforemain()andareusefulforsettingupenvorments和InitializingVariables.usethemforsimpletasks,避免使用輔助效果,andbecautiouswithTestingTestingTestingAndLoggingTomaintAnainCodeCodeCodeClarityAndTestesto。

goinitializespackagesintheordertheordertheyimported,thenexecutesInitFunctionswithinApcageIntheirdeFinityOrder,andfilenamesdetermineTheOrderAcractacractacrosmultiplefiles.thisprocessCanbeCanbeinepessCanbeInfleccessByendercrededBydeccredByDependenciesbetenciesbetencemendencenciesbetnependendpackages,whermayleLeadtocomplexinitialitialializizesizization

CustomInterfacesingoarecrucialforwritingFlexible,可維護,andTestableCode.TheyEnableDevelostOverostOcusonBehaviorBeiroveration,增強ModularityAndRobustness.byDefiningMethodSigntulSignatulSigntulSignTypaterSignTyperesthattypesmustemmustemmustemmustemplement,InterfaceSallowForCodeRepodEreusaperia

使用接口進行模擬和測試的原因是:接口允許定義合同而不指定實現方式,使得測試更加隔離和易於維護。 1)接口的隱式實現使創建模擬對像變得簡單,這些對像在測試中可以替代真實實現。 2)使用接口可以輕鬆地在單元測試中替換服務的真實實現,降低測試複雜性和時間。 3)接口提供的靈活性使得可以為不同測試用例更改模擬行為。 4)接口有助於從一開始就設計可測試的代碼,提高代碼的模塊化和可維護性。

在Go中,init函數用於包初始化。 1)init函數在包初始化時自動調用,適用於初始化全局變量、設置連接和加載配置文件。 2)可以有多個init函數,按文件順序執行。 3)使用時需考慮執行順序、測試難度和性能影響。 4)建議減少副作用、使用依賴注入和延遲初始化以優化init函數的使用。

go'SselectStatementTreamLinesConcurrentProgrambyMultiplexingOperations.1)itallowSwaitingOnMultipleChannEloperations,執行thefirstreadyone.2)theDefirstreadyone.2)thedefefcasepreventlocksbysbysbysbysbysbythoplocktrograpraproxrograpraprocrecrecectefnoopeready.3)

contextancandwaitgroupsarecrucialingoformanaginggoroutineseflect.1)context contextsallowsAllowsAllowsAllowsAllowsAllingCancellationAndDeadLinesAcrossapibiboundaries,確保GoroutinesCanbestoppedGrace.2)WaitGroupsSynChronizeGoroutines,確保Allimizegoroutines,確保AllizeNizeGoROutines,確保AllimizeGoroutines


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

Dreamweaver Mac版
視覺化網頁開發工具

VSCode Windows 64位元 下載
微軟推出的免費、功能強大的一款IDE編輯器

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

Safe Exam Browser
Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

Dreamweaver CS6
視覺化網頁開發工具