首頁 > 後端開發 > Golang > 主體

方法上的指標和值之間的區別

Linda Hamilton
發布: 2024-11-26 01:35:15
原創
351 人瀏覽過

The difference between pointers and values on methods

在 Go 中編寫方法時,關鍵決策之一是是否以值或指標傳遞結構體。此選擇會影響效能、程式碼行為和記憶體分配。在這篇文章中,我們將透過實際範例探討這種差異,並了解每種方法何時更合適。

讓我們從一個小結構體和兩個方法開始:一個結構體透過值傳遞,另一個透過指標傳遞。

package main

import (
    "fmt"
)

type Person struct {
    Name string
    Age  int
}

// Method with struct passed by value
func (p Person) CelebrateBirthdayValue() {
    p.Age++
}

// Method with struct passed by pointer
func (p *Person) CelebrateBirthdayPointer() {
    p.Age++
}

func main() {
    person := Person{Name: "Alice", Age: 30}

    // Passing by value
    person.CelebrateBirthdayValue()
    fmt.Println("After CelebrateBirthdayValue:", person.Age) // Output: 30

    // Passing by pointer
    person.CelebrateBirthdayPointer()
    fmt.Println("After CelebrateBirthdayPointer:", person.Age) // Output: 31
}
登入後複製
登入後複製

值和指標之間的區別

當我們將結構體以值傳遞給方法時,Go 會建立該結構體的副本。對方法內的結構體進行的任何更改都不會影響原始結構體,因為我們正在使用獨立的副本。

另一方面,當我們透過指標傳遞結構體時,我們傳遞的是原始結構體的記憶體位址。這意味著對方法內的結構體所做的任何更改都將直接修改原始結構體,因為我們正在操作同一個實例。

總結:

  • 按值: 此方法接收結構體的副本,建立一個新的記憶體空間。

  • 透過指標:此方法接收原始結構體的記憶體位址,指向同一記憶體空間。

堆疊

當結構按值傳遞時,副本會在堆疊上分配,這通常是快速且有效率的。但是,如果結構很大,則副本可能會消耗大量堆疊記憶體。

當透過指標傳遞結構時,指標本身會在堆疊上分配,但原始結構可能會在堆疊上分配,特別是當它是使用 new、make 建立或由匿名函數捕獲時。

堆分配在分配時間和垃圾收集方面更昂貴,但允許高效操作大量數據,而無需複製整個結構。

何時使用每種方法

按價值

以值傳遞結構在下列情況下很有用:

  • 您要確保原始結構不會被修改。
  • 結構體很小,複製它不會顯著影響性能。
  • 此方法只需讀取數據,無需更改內部狀態。

範例:

func (p Person) GetName() string {
    return p.Name
}
登入後複製

這裡,GetName 只讀取 Name 欄位並傳回一個字串,而不修改結構體的狀態。

透過指針

在以下情況下透過指標傳遞結構是有益的:

  • 需要修改原來的結構體。
  • 該結構體很大,複製其資料在記憶體和效能方面都會付出高昂的代價。
  • 您希望避免不必要的副本以提高程式碼效率。

範例:

package main

import (
    "fmt"
)

type Person struct {
    Name string
    Age  int
}

// Method with struct passed by value
func (p Person) CelebrateBirthdayValue() {
    p.Age++
}

// Method with struct passed by pointer
func (p *Person) CelebrateBirthdayPointer() {
    p.Age++
}

func main() {
    person := Person{Name: "Alice", Age: 30}

    // Passing by value
    person.CelebrateBirthdayValue()
    fmt.Println("After CelebrateBirthdayValue:", person.Age) // Output: 30

    // Passing by pointer
    person.CelebrateBirthdayPointer()
    fmt.Println("After CelebrateBirthdayPointer:", person.Age) // Output: 31
}
登入後複製
登入後複製

在這種情況下,UpdateName 直接修改原始結構體的 Name 字段,這比建立副本更有效率。

結論

在 Go 中編寫方法時決定是按值還是按指標傳遞結構體是一個重要的選擇,可能會影響效能、程式碼行為和記憶體分配。

按值傳遞對於確保方法內結構的不變性很有用,而按指標傳遞對於修改原始結構並在處理較大結構時最佳化效能至關重要。

以上是方法上的指標和值之間的區別的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:dev.to
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板