Notes et transcriptions du cours “Démarrer avec Go” proposée par University of California, Irvine disponible sur la plateforme coursera.
Dans ce module, nous allons donc parler des types de base, et nous allons commencer par les pointeurs, ce qui est peut-être un point de départ inhabituel pour aborder la question des types, mais c'est par là que nous commençons, car les personnes qui suivent ces cours s'y connaissent généralement déjà en programmation.
Passons donc directement à ces pointeurs et parlons-en. Un pointeur est une adresse vers certaines données en mémoire. Chaque variable, chaque fonction est située en mémoire quelque part. Un pointeur est leur adresse en mémoire.
Avec les pointeurs, nous avons deux principaux opérateurs associés :
&
, qui renvoie l'adresse de la variable ou de la fonction, quel que soit le nom auquel le nom fait référence ;*
, qui déréférence, fait le contraire de l'esperluette. Il renvoie les données à l'adresse.
Si vous placez l'opérateur esperluette &
devant le nom d' une variable, il vous renverra l'adresse de cette variable.
L'opérateur étoile *
agit de façon contraire. Si vous le placez devant un pointeur, (donc devant une adresse), il vous renverra les données à cette adresse. Il est donc important de comprendre que cet opérateur esperluette et cet opérateur étoile sont opposés l'un à l'autre.
Ci-dessous un exemple de code :
var x int = 1 var y int var ip *int // ip est un pointeur sur entier ip = &x // on affecte à ip l'adresse de x, ip pointe maintenant sur x y = *ip // on affecte à y la valeur pointée par ip, y = 1
Lignes 1 et 2, nous définissons une variable x
de type entier égale à un. y
est un entier et il n'est pas initialisé, ce qui signifierait qu'il serait initialisé par défaut à zéro.
Ligne 3, nous déclarons une variable ip
. ip
n'est pas déclarée comme étant de type int
, mais *int
. Cela signifie qu' ip
est un pointeur vers un entier. Donc, ip
est le pointeur, mais ce n'est une variable entière, c'est un pointeur vers un entier.
Ligne 5, on affecte à ip
la valeur &x
. x
est un entier dont la valeur est 1
. Il y a donc le chiffre 1
quelque part en mémoire, et le label x
y fait référence. &x
est l'adresse en mémoire où je peux trouver cette valeur 1
. ip
est donc désormais égal à cette adresse. Quelle que soit la position en mémoire de x
, ip
est cette adresse.
Ligne 6, on affecte à y
la valeur *ip
. Dans ce petit exemple, ip
est un pointeur et la donnée à l' adresse pointée est la valeur 1
. L'opérateur, *ip
, permet de faire un déréférencement. L'opérateur *
renvoie la valeur des données à cette adresse. Ainsi, y
est désormais égal aux données de l'adresse vers laquelle pointe l'adresse ip
c'est à dire 1
.
Ce n'est qu'un petit exemple, qui essaie simplement de montrer comment les opérateur &
et *
fonctionnent.
La fonction new
est une autre façon de créer une variable. Au lieu de renvoyer une variable, new
crée la variable et renvoie un pointeur vers la variable.
Donc, ce n'est pas la même chose que de déclarer simplement une variable. Cela permet de créer également une variable, mais new() renvoie explicitement un pointeur vers une variable.
Lors de la création avec new(), la variable reçoit une initialisation par défaut (0 pour un entier). Dans l'extrait de code ci dessous, on peut voir comment affecter la valeur souhaitée après création de la variable:
ptr := new(int) *ptr = 3
new(int) renvoie un pointeur vers un entier affecté à ptr
. On peut définir la valeur de cet entier en utilisant *ptr
car *ptr
désigne la valeur vers laquelle pointe ptr
. En écrivant *ptr = 3
, la valeur 3
est placée à l'adresse spécifiée par ptr
.