Modification des valeurs de type simple via les méthodes de récepteur de pointeur dans Go
Dans Go, nous pouvons créer des types personnalisés basés sur les types de base et étendre leurs fonctionnalités via des méthodes de récepteur de pointeur. Cependant, une question courante se pose lorsque l'on tente de modifier la valeur d'un type simple via une méthode de réception de pointeur.
Considérons l'exemple suivant :
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 }
Pourquoi le pointeur fi déclaré dans main() ne change pas sa valeur à l'adresse de tmp?
Explication
Lorsque vous appelez une fonction ou une méthode dans Go, tous les arguments, y compris le récepteur, sont transmis sous forme de copies. Cela signifie que vous ne pouvez pas modifier la valeur originale du pointeur depuis la fonction/méthode.
Dans l'exemple ci-dessus, fi dans la méthode FromString est une copie du pointeur déclaré dans main(). Lorsque vous attribuez fi à l'adresse de tmp, vous modifiez uniquement la valeur de la copie. Le pointeur d'origine reste inchangé.
Solutions
Il existe trois solutions courantes à ce problème :
1. Renvoyer un pointeur :
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. Passer un argument de pointeur :
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. Assurer un récepteur non nul :
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 }
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!