Maison >développement back-end >Golang >Comment fonctionne le déréférencement de pointeur dans Go et pourquoi les résultats sont-ils parfois inattendus ?

Comment fonctionne le déréférencement de pointeur dans Go et pourquoi les résultats sont-ils parfois inattendus ?

Barbara Streisand
Barbara Streisandoriginal
2024-11-30 12:47:11798parcourir

How Does Pointer Dereferencing Work in Go, and Why Are the Results Sometimes Unexpected?

Exploration du déréférencement de pointeur dans Go

Dans le langage de programmation Go, les pointeurs jouent un rôle crucial dans la manipulation des données, en particulier lorsque vous travaillez avec des structures. La possibilité de déréférencer des pointeurs constitue un moyen puissant d’accéder et de modifier indirectement les données. Dans cette discussion, nous explorons les mécanismes de déréférencement de pointeur dans Go, dévoilant les surprises qui peuvent survenir.

La surprise du déréférencement de pointeur

Considérez l'extrait de code Go suivant :

package main

import "fmt"

type Vertex struct {
    X, Y int
}

func main() {
    p := Vertex{1, 2}  // has type Vertex
    q := &p // has type *Vertex
    t := *q
    q.X = 4
    u := *q
    fmt.Println(p, q, t, u, t == u)
}

Lors de son exécution, ce code produit le sortie :

{1 2} &{4 2} {1 2} {4 2} false

Le résultat inattendu est que t conserve la valeur d'origine de q, même si q.X a été modifié. Ce comportement découle de la nature du déréférencement du pointeur dans Go.

Dévoilement de la vérité : déréférencement du pointeur

Lors de l'accès à une valeur via un pointeur, Go déréférence le pointeur, essentiellement fournir une copie temporaire de la valeur pointée. Dans notre exemple, lorsque nous déréférençons q pour créer t, nous obtenons une copie de la structure Vertex. Par conséquent, toute modification apportée à q ne sera pas reflétée dans t.

Pour observer les changements de q à t, nous devons maintenir la relation de pointeur. Le code modifié suivant illustre ceci :

package main

import "fmt"

type Vertex struct {
    X, Y int
}

func main() {
    p := Vertex{1, 2}  // has type Vertex
    q := &p // has type *Vertex
    t := q
    q.X = 4
    u := *q
    fmt.Println(p, q, t, u, *t == u)
}

Cette fois, la sortie reflète le comportement attendu :

{1 2} &{4 2} &{4 2} {4 2} true

En préservant la relation de pointeur entre q et t, nous nous sommes assurés que les modifications apportées à q serait propagé à t.

Parallèles en C et C

Il est important de noter que le comportement de déréférencement du pointeur dans Go est cohérent avec celui de langages comme C et C.

struct Vertex {
    int x;
    int y;
};

int main() {
    Vertex v = {1, 2};
    Vertex* q = &v;
    Vertex t = *q;
    q->x = 4;
    std::cout << "*q: " << *q << "\n";
    std::cout << " t: " << t << "\n";
}

L'exécution de ce code C produit une sortie identique à celle de Go , renforçant le fait que le comportement de déréférencement de pointeur suit des principes similaires dans ces langages.

En conclusion, alors que le déréférencement de pointeur dans Go peut paraître surprenant au premier abord, il fonctionne de manière logique et cohérente. En comprenant que le déréférencement crée des copies temporaires, les programmeurs peuvent exploiter efficacement les pointeurs pour naviguer et manipuler les structures de données avec précision.

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