假設(shè)有以下三個方法
type MyStruct struct {
Val int
}
func myfunc() MyStruct {
return MyStruct{Val: 1}
}
func myfunc() *MyStruct {
return &MyStruct{}
}
func myfunc(s *MyStruct) {
s.Val = 1
}
- 第一個方法返回
MyStruct{Val:1}
的復(fù)制 - 第二個方法在函數(shù)內(nèi)創(chuàng)建
MyStruct{Val:1}
的指針段标,將其返回 - 第三個方法需要傳入一個
MyStruct
,然后函數(shù)會覆蓋其值
這三種情況在各大源碼中都有出現(xiàn)糟红,但其作用相同曹抬,那么在這三種方式中進行選擇的最佳實踐是什么呢特恬?
簡要回答
- 大多數(shù)情況下使用指針傳遞悠砚。google開發(fā)組的經(jīng)驗是:“當(dāng)你不知道改選擇什么進行傳遞時士嚎,就使用指針吧”
- Slices, maps, channels, strings, function values, 和 interface values本身就是使用指針實現(xiàn)的,所以再使用指針傳遞是多余的
- 對于打的結(jié)構(gòu)體师倔,或者不得不修改的結(jié)構(gòu)體傳指針构韵,否則傳值,因為由于傳遞指針導(dǎo)致結(jié)構(gòu)體被修改的問題很難被排查
詳細(xì)分析
大多數(shù)情況下都要使用指針傳遞
- 因為函數(shù)經(jīng)常要修改傳遞過來的參數(shù),所以在go語言指導(dǎo)中贞绳,推薦使用指針傳遞,但也有極少部分需要使用值傳遞致稀,如:
- copyfighter 使用值來傳遞
還有一些情況不需要使用指針
- google代碼審查小組提倡對不需要函數(shù)進行修改的冈闭、小的結(jié)構(gòu)體中使用值傳遞,例如
type Point struct { latitude, longitude float64 }
- 值傳遞可以避免由于別名而帶來的值的修改錯誤
- 有時使用小的結(jié)構(gòu)體的值進行參數(shù)傳遞可以避免緩存未命中或者重新分配堆空間
- 對于slice抖单,是沒有必要使用指針傳遞的萎攒,參考Go數(shù)據(jù)結(jié)構(gòu)探究
大結(jié)構(gòu)體和小結(jié)構(gòu)體如何區(qū)分
沒有相關(guān)知道,需要自己判斷