Maison > développement back-end > Golang > le corps du texte

## Pourquoi la copie d'instances de types Go avec des méthodes de récepteur de pointeur est-elle dangereuse ?

Linda Hamilton
Libérer: 2024-10-25 10:54:30
original
201 Les gens l'ont consulté

## Why is Copying Instances of Go Types with Pointer Receiver Methods Dangerous?

Pièges de la copie d'instances avec des méthodes de récepteur de pointeur

En Go, si toutes les méthodes pour un type nommé T ont un type de récepteur de T lui-même (et non *T), la copie d'instances de ce type est considérée comme sûre. En effet, tout appel de méthode opère nécessairement sur une copie, garantissant que la valeur d'origine reste inchangée. Cependant, si une méthode pour T a un récepteur de pointeur, copier des instances de T peut être dangereux.

Explication

Lors de l'appel d'une méthode, la valeur que la méthode est invoquée on est d'abord copié et la copie est transmise en tant que récepteur. Si un type ne possède que des méthodes avec des récepteurs de valeur, cela garantit que les méthodes ne peuvent pas modifier la valeur d'origine, quelles que soient leurs actions. En effet, une copie est toujours utilisée, protégeant l'original des modifications involontaires.

Cependant, si un type possède des méthodes avec des récepteurs de pointeurs, ces méthodes peuvent modifier la valeur pointée d'origine plutôt que sa copie. En effet, la méthode reçoit un pointeur vers la valeur d'origine, lui permettant de modifier les données sous-jacentes.

Exemple

Considérons un wrapper de type Wrapper :

type Wrapper struct {
    v int
    p *int
}
Copier après la connexion

Avec une méthode Set() pour s'assurer que les deux champs contiennent la même valeur :

func (w *Wrapper) Set(v int) {
    w.v = v
    *w.p = v
}
Copier après la connexion

Si nous créons une instance de Wrapper :

a := Wrapper{v: 0, p: new(int)}
Copier après la connexion

Et faisons ensuite un copie (b) de a :

b := a
Copier après la connexion

Après avoir défini a sur 1 à l'aide de Set() :

a.Set(1)
Copier après la connexion

Nous nous attendons à ce que a et b aient leurs champs définis sur 1. Cependant, l'impression de leurs valeurs révèle une autre histoire :

fmt.Printf("a.v=%d, a.p=%d;  b.v=%d, b.p=%d\n", a.v, *a.p, b.v, *b.p)
Copier après la connexion

Sortie :

a.v=1, a.p=1;  b.v=0, b.p=1
Copier après la connexion

La raison de cet écart est que même si le pointeur dans b est copié, il fait toujours référence au même données sous-jacentes comme pointeur dans a. Lorsque Set() modifie la valeur pointée, cela affecte les deux copies de Wrapper. Cependant, le champ non-pointeur v reste distinct entre a et b.

Bonne pratique

Pour éviter ce problème, il est recommandé de s'abstenir de copier des instances de types avec méthodes de récepteur de pointeur. Si travailler avec des valeurs de pointeur est nécessaire, copier le pointeur lui-même (*T) est une alternative viable.

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
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!