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()) }
Ausgabe
Test1 final: [0 1] Test2 final: [0 1] Test3 step 1 [0] Test3 step 2 [0 1] Test3 final: [0 1]
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!