Ändern einfacher Typwerte durch Zeigerempfängermethoden in Go
In Go können wir benutzerdefinierte Typen basierend auf Basistypen erstellen und deren Funktionalität erweitern durch Zeigerempfängermethoden. Beim Versuch, den Wert eines einfachen Typs über eine Zeigerempfängermethode zu ändern, stellt sich jedoch häufig die Frage.
Betrachten Sie das folgende Beispiel:
package main import ( "fmt" "strconv" ) type FooInt int func (fi *FooInt) FromString(i string) { num, _ := strconv.Atoi(i) tmp := FooInt(num) fi = &tmp // Attempt to modify the pointer } func main() { var fi *FooInt fi.FromString("5") fmt.Printf("%v\n", fi) // Prints <nil>, not the expected 5 }
Warum funktioniert der Zeiger? in main() deklariert seinen Wert nicht in die Adresse von tmp ändern?
Erklärung
Wenn Sie eine Funktion oder Methode in Go aufrufen, werden alle Argumente, einschließlich des Empfängers, angezeigt , werden als Kopien weitergegeben. Dies bedeutet, dass Sie den ursprünglichen Zeigerwert nicht innerhalb der Funktion/Methode ändern können.
Im obigen Beispiel ist fi in der FromString-Methode eine Kopie des in main() deklarierten Zeigers. Wenn Sie fi der Adresse von tmp zuweisen, ändern Sie nur den Wert der Kopie. Der ursprüngliche Zeiger bleibt unverändert.
Lösungen
Es gibt drei gängige Lösungen für dieses Problem:
1. Einen Zeiger zurückgeben:
func (fi *FooInt) FromString(i string) *FooInt { num, _ := strconv.Atoi(i) tmp := FooInt(num) return &tmp } func main() { var fi *FooInt fi = fi.FromString("5") fmt.Printf("%v %v\n", fi, *fi) // Prints 0xc0000b4020 5 }
2. Übergabe eines Zeigerarguments:
func (fi *FooInt) FromString(i string, p **FooInt) { num, _ := strconv.Atoi(i) tmp := FooInt(num) *p = &tmp } func main() { var fi *FooInt fi = new(FooInt) // Ensure non-nil receiver fi.FromString("5", &fi) fmt.Printf("%v %v\n", fi, *fi) // Prints 0xc0000b4020 5 }
3. Sicherstellen, dass der Empfänger nicht Null ist:
func (fi *FooInt) FromString(i string) { num, _ := strconv.Atoi(i) *fi = FooInt(num) } func main() { var fi *FooInt fi = new(FooInt) // Ensure non-nil receiver fi.FromString("5") fmt.Printf("%v %v\n", fi, *fi) // Prints 0xc0000b4020 5 }
Das obige ist der detaillierte Inhalt vonWarum kann ich einen einfachen Typwert nicht über eine Zeigerempfängermethode in Go ändern?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!