Heim > Backend-Entwicklung > Golang > Warum benötige ich einen Zeigerempfänger zum Anhängen an ein Slice in einer Go-Struktur?

Warum benötige ich einen Zeigerempfänger zum Anhängen an ein Slice in einer Go-Struktur?

Mary-Kate Olsen
Freigeben: 2024-12-27 17:39:12
Original
258 Leute haben es durchsucht

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

Anhängen an Slice-Eigenschaften in Go-Strukturen

Beim Versuch, Werte an eine Slice-Eigenschaft innerhalb einer Go-Struktur anzuhängen, kann es zu unerwartetem Verhalten kommen wenn eine bestimmte Abrufreihenfolge nicht befolgt wird. In diesem Artikel werden die Gründe für dieses Problem untersucht und eine Lösung bereitgestellt.

Im bereitgestellten Codebeispiel werden drei Methoden in verschiedenen Strukturtypen definiert, um das Problem zu veranschaulichen. Test1 und Test2 funktionieren wie erwartet, da ihre run()-Methoden direkt mit der Slice-Eigenschaft arbeiten. In Test3 wird die Methode „combo()“ jedoch von run() mit einem Wertempfänger anstelle eines Zeigerempfängers aufgerufen.

Warum ein Zeigerempfänger erforderlich ist

In Go werden alle Werte als Wert übergeben, d. h. beim Aufruf einer Funktion oder Methode wird eine Kopie des übergebenen Werts erstellt. Im Fall von Test3 wird beim Aufruf von Combo() eine Kopie des Test3-Werts erstellt, und Änderungen an der Slice-Eigenschaft in dieser Kopie werden nicht in der ursprünglichen Test3-Struktur widergespiegelt.

Durch Verwendung eines Zeigerempfängers B. func (c *Test3) Combo(), wird die ursprüngliche Test3-Struktur direkt geändert, wodurch das Problem der lokalen Kopie beseitigt wird Änderungen.

Lösung

Die Lösung besteht darin, den Empfängertyp der Methode „combo()“ in einen Zeigerempfänger zu ändern. Dadurch wird sichergestellt, dass die ursprüngliche Test3-Struktur durch die Methode geändert wird.

Aktualisierter Code

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())
}
Nach dem Login kopieren

Ausgabe

Test1 final: [0 1]
Test2 final: [0 1]
Test3 step 1 [0]
Test3 step 2 [0 1]
Test3 final: [0 1]
Nach dem Login kopieren

Das obige ist der detaillierte Inhalt vonWarum benötige ich einen Zeigerempfänger zum Anhängen an ein Slice in einer Go-Struktur?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage