Golang中如何判斷該用指針還是值類型 從內(nèi)存和性能角度給出決策指南

go語言中,選擇指針類型還是值類型主要取決于結(jié)構(gòu)體大小和是否需要修改原始數(shù)據(jù)。1. 結(jié)構(gòu)體較大或包含大塊數(shù)據(jù)(如數(shù)組、切片map等)時,優(yōu)先使用指針以減少內(nèi)存開銷和性能損耗;2. 如果函數(shù)需要修改傳入的數(shù)據(jù),必須使用指針,因為go是按值傳遞的;3. 涉及接口實現(xiàn)時,值接收者可以讓結(jié)構(gòu)體和指針都實現(xiàn)接口,更靈活,而大結(jié)構(gòu)體建議用指針接收者避免復(fù)制;4. 小結(jié)構(gòu)體或只讀訪問時可使用值類型,避免副作用且不影響性能。

Golang中如何判斷該用指針還是值類型 從內(nèi)存和性能角度給出決策指南

go語言中,什么時候用指針類型、什么時候用值類型,其實是一個挺常見的問題。這個問題沒有統(tǒng)一的答案,但可以根據(jù)內(nèi)存使用和性能表現(xiàn)來做一個大致的判斷。

Golang中如何判斷該用指針還是值類型 從內(nèi)存和性能角度給出決策指南

簡單來說:如果你希望函數(shù)修改變量本身,并且這個變量比較大,就該用指針;否則可以考慮用值類型。

Golang中如何判斷該用指針還是值類型 從內(nèi)存和性能角度給出決策指南

下面從幾個實際場景出發(fā),具體講講怎么選。

立即學(xué)習go語言免費學(xué)習筆記(深入)”;


結(jié)構(gòu)體大小影響性能

Go中的結(jié)構(gòu)體默認是值類型,當你把一個結(jié)構(gòu)體傳給函數(shù)時,默認是復(fù)制整個結(jié)構(gòu)體。如果結(jié)構(gòu)體很大,比如有幾十個字段,或者包含大數(shù)組、嵌套結(jié)構(gòu)體,那么頻繁傳遞這樣的值會帶來額外的內(nèi)存開銷和性能損耗。

Golang中如何判斷該用指針還是值類型 從內(nèi)存和性能角度給出決策指南

舉個例子:

type User struct {     Name   String     Age    int     Email  string     Avatar [1024]byte // 假設(shè)頭像數(shù)據(jù)較大 }

這個User結(jié)構(gòu)體不算小,每次傳參都會復(fù)制一份。這時候就應(yīng)該考慮用指針了:

func updateUser(u *User) {     u.Age = 30 }

?建議:結(jié)構(gòu)體字段多或包含大塊數(shù)據(jù)(如數(shù)組、切片、map等)時,優(yōu)先使用指針。如果結(jié)構(gòu)體很小,比如只有兩三個int或string字段,傳值也沒關(guān)系。


是否需要修改原始數(shù)據(jù)

另一個關(guān)鍵點是:你是否需要通過函數(shù)調(diào)用修改原始變量?

如果你寫了一個函數(shù),想讓它修改傳入的對象,那就必須用指針。因為Go是“按值傳遞”的,傳進去的是副本。

例如:

func setName(u User, name string) {     u.Name = name }

這樣調(diào)用后,原對象的Name不會變。必須改成:

func setName(u *User, name string) {     u.Name = name }

?建議:

  • 如果函數(shù)要修改傳入的數(shù)據(jù),用指針。
  • 如果只是讀取數(shù)據(jù),可以傳值,避免副作用。

接口實現(xiàn)與方法集

在Go中,方法接收者是指針還是值,會影響它能實現(xiàn)哪些接口。

比如你有一個接口:

type speaker interface {     Speak() }

然后定義兩個方法:

func (u User) Speak() { fmt.Println("Hi") } func (u *User) Speak() { fmt.Println("Hi") }

前者是值方法,后者是指針方法。它們的行為略有不同:

  • 指針方法:*User 實現(xiàn)了接口,但 User 類型不實現(xiàn)。
  • 值方法:User 和 *User 都實現(xiàn)了接口。

所以,如果你希望無論傳值還是指針都能滿足接口要求,最好用值接收者。

?建議:

  • 如果你的結(jié)構(gòu)體會被作為接口實現(xiàn)使用,注意接收者的類型選擇。
  • 小結(jié)構(gòu)體用值接收者更靈活,大結(jié)構(gòu)體建議用指針接收者避免復(fù)制。

總結(jié)一下

  • 結(jié)構(gòu)體大 → 用指針
  • 需要修改原對象 → 用指針
  • 只讀訪問或結(jié)構(gòu)體小 → 可以用值
  • 涉及接口實現(xiàn) → 看接收者類型

基本上就這些,看似簡單,但細節(jié)容易忽略。

? 版權(quán)聲明
THE END
喜歡就支持一下吧
點贊15 分享