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
Libérer: 2024-11-19 01:12:02
original
355 Les gens l'ont consulté

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
}
Copier après la connexion

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
}
Copier après la connexion

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
}
Copier après la connexion

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
}
Copier après la connexion

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!

source:php.cn
Déclaration de ce site Web
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
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal