Maison >développement back-end >Golang >Pourquoi la modification d'un type simple via une méthode de réception de pointeur dans Go ne fonctionne-t-elle pas comme prévu ?

Pourquoi la modification d'un type simple via une méthode de réception de pointeur dans Go ne fonctionne-t-elle pas comme prévu ?

Patricia Arquette
Patricia Arquetteoriginal
2024-11-16 12:29:03236parcourir

Why Does Modifying a Simple Type Through a Pointer Receiver Method in Go Not Work as Expected?

Comment modifier les valeurs de types simples via les méthodes de récepteur de pointeur dans Go

Lorsque vous travaillez avec des types personnalisés basés sur des types de base, vous souhaiterez peut-être pour modifier leurs valeurs à l'aide des fonctions du récepteur pointeur. Cependant, lorsque vous essayez de le faire, vous pouvez rencontrer un scénario dans lequel les modifications semblent inefficaces. Voici une explication détaillée :

Le problème

Considérez le code suivant :

package main

import "fmt"

type FooInt int

func (fi *FooInt) FromString(i string) {
    num, _ := strconv.Atoi(i)
    tmp := FooInt(num)
    fi = &tmp // Attempting to modify the pointer
}

func main() {
    var fi *FooInt
    fi.FromString("5")
    fmt.Println(fi) // Prints nil
}

Lorsque vous exécutez ce programme, vous remarquerez que la valeur de fi reste nulle malgré la tentative de la méthode FromString de la modifier.

Explication

Dans Go, tous les arguments de la fonction, y compris le récepteur, sont transmis par valeur. Cela signifie qu'à l'intérieur de la méthode FromString, le pointeur fi est une copie du pointeur réel déclaré dans main. Lorsque vous modifiez fi dans la méthode, vous modifiez uniquement la copie, pas le pointeur d'origine.

Pour résoudre ce problème, vous avez deux options :

1. Renvoyer le pointeur modifié

Vous pouvez renvoyer le pointeur modifié à partir de la méthode FromString et le réaffecter au pointeur d'origine :

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.Println(fi) // Prints the address of the modified pointer
}

2. Assurez-vous que le récepteur est non nul

Alternativement, vous pouvez vous assurer que le récepteur n'est pas nul avant d'essayer de modifier la valeur pointée :

func (fi *FooInt) FromString(i string) {
    if fi == nil {
        fi = new(FooInt) // Initialize fi if it's nil
    }
    num, _ := strconv.Atoi(i)
    *fi = FooInt(num)
}

func main() {
    var fi *FooInt
    fi.FromString("5")
    fmt.Println(fi) // Prints the address of the modified pointer
}

Cela garantit que le récepteur est initialisé et la valeur pointée peut être modifiée directement.

En résumé, lors de la modification de valeurs via les méthodes de récepteur de pointeur dans Go, n'oubliez pas que le récepteur est une copie et vous devez soit renvoyer le pointeur modifié, soit vous assurer que le récepteur est non nul pour éviter un comportement inattendu.

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