Maison >développement back-end >Golang >Pourquoi ne puis-je pas modifier une valeur de type simple via une méthode de réception de pointeur dans Go ?

Pourquoi ne puis-je pas modifier une valeur de type simple via une méthode de réception de pointeur dans Go ?

Barbara Streisand
Barbara Streisandoriginal
2024-11-19 01:12:02342parcourir

Why Can't I Modify a Simple Type Value Through a Pointer Receiver Method in Go?

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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn