首頁 >後端開發 >Golang >為什麼我需要一個指標接收器來附加到 Go 結構中的切片?

為什麼我需要一個指標接收器來附加到 Go 結構中的切片?

Mary-Kate Olsen
Mary-Kate Olsen原創
2024-12-27 17:39:12270瀏覽

Why Do I Need a Pointer Receiver to Append to a Slice in a Go Struct?

當附加到Go 結構中的切片屬性

嘗試將值附加到Go 結構中的切片屬性時,您可能會遇到意外行為如果未遵循特定的呼叫順序。本文探討了此問題背後的原因並提供了解決方案。

在提供的程式碼範例中,在不同的結構類型中定義了三個方法來示範該問題。 Test1 和 Test2 按預期工作,因為它們的 run() 方法直接對切片屬性進行操作。然而,在 Test3 中,combo() 方法是使用值接收器而不是指標接收器從 run() 呼叫的。

為什麼需要指標接收器

在Go 中,所有值都是按值傳遞,這表示在呼叫函數或方法時會建立傳遞值的副本。在 Test3 的情況下,呼叫combo() 時會建立 Test3 值的副本,並且對該副本中的 slice 屬性的修改不會反映在原始 Test3 結構中。

透過使用指標接收器,如func(c *Test3)combo(),直接修改原先的Test3結構體,消除了copy-local的問題

解決方案是將combo()方法的接收者類型變更為指標接收者。這確保原始 Test3 結構體被該方法修改。

更新的程式碼

package main

import (
  "fmt"
)

type Test1 struct {
  all []int
}

func (c Test1) run() []int {
  for i := 0; i < 2; i++ {
    c.all = append(c.all, i)
  }
  return c.all
}

var gloabl_all []int

type Test2 struct {}

func (c Test2) run() []int {
  c.combo()
  return gloabl_all
}

func (c Test2) combo() {
  for i := 0; i < 2; i++ {
    gloabl_all = append(gloabl_all, i)
  }
}

type Test3 struct {
  all []int
}

func (c Test3) run() []int {
  c.combo()
  return c.all
}

func (c *Test3) combo() {
  for i := 0; i < 2; i++ {
    c.all = append(c.all, i)
    fmt.Println("Test3 step", i + 1, c.all)
  }
}

func main() {
  test1 := &Test1{}
  fmt.Println("Test1 final:", test1.run())

  test2 := &Test2{}
  fmt.Println("Test2 final:", test2.run())

  test3 := &Test3{}
  fmt.Println("Test3 final:", test3.run())
}

輸出

Test1 final: [0 1]
Test2 final: [0 1]
Test3 step 1 [0]
Test3 step 2 [0 1]
Test3 final: [0 1]

以上是為什麼我需要一個指標接收器來附加到 Go 結構中的切片?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn