Découvrir les types de données de base
Go est un langage fortement typé. Chaque variable que vous déclarez est liée à un type de données spécifique et accepte uniquement les valeurs qui correspondent à ce type.
En Go, vous avez quatre catégories de types de données :
- Types de base : nombres, chaînes et valeurs booléennes
- Types d’agrégats : tableaux et structs
- Types référence : pointeurs, coupes, mappages, fonctions et canaux
- Types d’interface : interface
Dans ce module, nous ne couvrons que les types de base. Ne vous inquiétez pas si vous ne savez pas quels sont les autres types. Nous les aborderons dans les prochains modules.
Commençons par explorer les types de données numériques.
Nombres entiers
En général, le mot clé permettant de définir un type entier est int
. Toutefois, Go fournit également les types int8
, int16
, int32
et int64
, qui sont des entiers avec une taille de 8, 16, 32 ou 64 bits, respectivement. Lorsque vous utilisez un système d’exploitation 32 bits, la taille est généralement de 32 bits si vous utilisez juste int
. Sur les systèmes 64 bits, la taille de int
est généralement de 64 bits. Mais ce comportement peut varier d’un ordinateur à un autre. Vous pouvez utiliser uint
. Utilisez ce type uniquement si vous devez représenter une valeur sous la forme d’un nombre non signé pour une raison spécifique. Go fournit également les types uint8
, uint16
, uint32
et uint64
.
Voici un exemple d’utilisation des différents types d’entiers en Go :
var integer8 int8 = 127
var integer16 int16 = 32767
var integer32 int32 = 2147483647
var integer64 int64 = 9223372036854775807
fmt.Println(integer8, integer16, integer32, integer64)
La plupart du temps, vous utilisez int
, mais vous devez connaître les autres types d’entiers car, en Go, int
n’est pas identique à int32
, même si la taille naturelle de l’entier est de 32 bits. En d’autres termes, vous devez effectuer un cast explicite quand un cast est nécessaire. En outre, si vous essayez d’effectuer une opération mathématique entre différents types, vous obtenez une erreur. Par exemple, si vous avez le code suivant :
var integer16 int16 = 127
var integer32 int32 = 32767
fmt.Println(integer16 + integer32)
Quand vous exécutez le programme, vous obtenez l’erreur suivante :
invalid operation: integer16 + integer32 (mismatched types int16 and int32)
Comme vous pouvez le voir, quand vous convertissez une valeur d’un type en un autre en Go, vous devez déclarer explicitement le nouveau type. Nous verrons comment correctement caster des types à la fin de ce module.
Au fil de votre apprentissage de Go, vous êtes susceptible d’entendre parler des runes. Un rune
est simplement un alias pour le type de données int32
. Il est utilisé pour représenter un caractère Unicode (ou un point de code Unicode). Par exemple, supposons que vous avez le code suivant :
rune := 'G'
fmt.Println(rune)
Il est possible que vous vous attendiez à ce que le programme affiche G
au niveau de l’invite de commandes si vous exécutez l’extrait de code précédent. Toutefois, vous voyez le nombre 71
, qui représente le caractère Unicode pour G
. Nous aborderons davantage les runes dans les prochains modules.
Vous pouvez découvrir les plages de chaque type en examinant le code source de Go. La connaissance des plages de chaque type vous aide à choisir le type de données approprié et vous évite également de gaspiller des bits dans la mémoire.
Défi 1
Définissez une autre variable de type int
et utilisez la valeur de la variable integer32
ou integer64
pour vérifier la taille naturelle de la variable sur votre système. Si vous êtes sur un système 32 bits et que vous utilisez une valeur supérieure à 2 147 483 647, vous obtenez une erreur de dépassement de capacité qui ressemble à celle-ci : constant 9223372036854775807 overflows int
.
Solution au défi :
package main import "fmt" func main() { var integer32 int = 2147483648 fmt.Println(integer32) }
Défi 2
Déclarez une variable non signée comme uint
et initialisez-la avec une valeur négative comme -10
. Quand vous essayez d’exécuter le programme, vous devez recevoir une erreur semblable à celle-ci : constant -10 overflows uint
.
Solution au défi :
package main import "fmt" func main() { var integer uint = -10 fmt.Println(integer) }
Nombres à virgule flottante
Go fournit des types de données pour deux tailles de nombres à virgule flottante : float32
et float64
. Vous pouvez utiliser ces types quand vous devez stocker des nombres élevés et qu’ils ne tiennent pas dans l’un des types d’entiers mentionnés plus haut. La différence entre ces deux types est la taille maximale de bits qu’ils peuvent contenir. Examinez les lignes suivantes pour savoir comment utiliser ces deux types :
var float32 float32 = 2147483647
var float64 float64 = 9223372036854775807
fmt.Println(float32, float64)
Vous pouvez trouver les limites de ces deux types à l’aide des constantes math.MaxFloat32
et math.MaxFloat64
, qui sont disponibles dans le package math
. Utilisez le code suivant pour afficher les valeurs à virgule flottante maximales au niveau de l’invite de commandes :
package main
import (
"fmt"
"math"
)
func main() {
fmt.Println(math.MaxFloat32, math.MaxFloat64)
}
Les types à virgule flottante sont également utiles quand vous devez utiliser des nombres décimaux. Par exemple, vous pouvez écrire un code similaire à celui-ci :
const e = 2.71828
const Avogadro = 6.02214129e23
const Planck = 6.62606957e-34
Notez qu’avec le code précédent, Go déduit les types de données à partir des valeurs utilisées.
valeurs booléennes
Un type booléen n’a que deux valeurs possibles : true
et false
. Vous déclarez un type booléen en utilisant le mot clé bool
. Go est différent des autres langages de programmation. En Go, vous ne pouvez pas convertir implicitement un type booléen en valeur 0 ou 1. Vous devez le faire explicitement.
Vous pouvez donc déclarer une variable booléenne comme suit :
var featureFlag bool = true
Nous utiliserons des types de données booléens dans le prochain module quand nous aborderons les instructions de flux de contrôle en Go. Nous les utiliserons également dans les modules ultérieurs.
Chaînes
Enfin, examinons le type de données le plus courant dans n’importe quel langage de programmation : chaîne. En Go, le mot clé string
est utilisé pour représenter un type de données chaîne. Pour initialiser une variable de chaîne, vous devez définir sa valeur entre des guillemets doubles ("
). Les guillemets simples ('
) sont utilisés pour les caractères uniques (et pour les runes, comme nous l’avons vu dans une section précédente).
Par exemple, le code suivant montre deux façons de déclarer et d’initialiser une variable de chaîne :
var firstName string = "John"
lastName := "Doe"
fmt.Println(firstName, lastName)
Vous êtes parfois amené à placer des caractères dans une séquence d’échappement. En Go, vous utilisez une barre oblique inverse (\
) avant le caractère. Voici les exemples les plus courants d’utilisation de caractères d’échappement :
\n
pour les nouvelles lignes\r
pour les retours chariot\t
pour les tabulations\'
pour les guillemets simples\"
pour les guillemets doubles\\
pour les barres obliques inverses
Utilisez l’extrait de code suivant pour tester les caractères d’échappement :
fullName := "John Doe \t(alias \"Foo\")\n"
fmt.Println(fullName)
Vous devez voir la sortie suivante (y compris la nouvelle ligne) :
John Doe (alias "Foo")
Valeurs par défaut
Jusqu’à présent, presque à chaque fois que nous avons déclaré une variable, nous l’avons initialisée avec une valeur. Mais en Go, contrairement à d’autres langages de programmation, tous les types de données ont une valeur par défaut quand vous n’initialisez pas une variable. Cette fonctionnalité est pratique, car vous n’avez pas besoin de vérifier si une variable a été initialisée avant de l’utiliser.
Voici une liste de quelques valeurs par défaut pour les types que nous avons explorés jusqu’à présent :
0
pour les typesint
(et tous ses sous-types, commeint64
)+0.000000e+000
pour les typesfloat32
etfloat64
false
pour les typesbool
- Valeur vide pour les types
string
Exécutez l’extrait de code suivant pour vérifier les valeurs par défaut listées ci-dessus :
var defaultInt int
var defaultFloat32 float32
var defaultFloat64 float64
var defaultBool bool
var defaultString string
fmt.Println(defaultInt, defaultFloat32, defaultFloat64, defaultBool, defaultString)
Vous pouvez utiliser du code tel que celui-ci pour déterminer la valeur par défaut d’un type de données que nous n’avons pas exploré ici.
Conversions des types
Dans une section précédente, nous avons vu que le cast implicite ne fonctionne pas en Go. En Go, le cast doit être effectué explicitement. Go offre des méthodes natives pour convertir un type de données en un autre. Par exemple, l’une des méthodes consiste à utiliser la fonction intégrée pour chaque type, comme suit :
var integer16 int16 = 127
var integer32 int32 = 32767
fmt.Println(int32(integer16) + integer32)
Une autre approche pour effectuer un cast en Go consiste à utiliser le package strconv. Par exemple, pour convertir un string
en int
, et vice versa, vous pouvez utiliser ce code :
package main
import (
"fmt"
"strconv"
)
func main() {
i, _ := strconv.Atoi("-42")
s := strconv.Itoa(-42)
fmt.Println(i, s)
}
Exécutez le code précédent ; il doit normalement afficher -42
deux fois.
Notez qu’un trait de soulignement (_
) est utilisé comme nom d’une variable dans le code précédent. En Go, _
indique que nous n’allons pas utiliser la valeur de cette variable et que nous voulons l’ignorer. Sinon, le programme n’est pas compilé, car nous devons utiliser toutes les variables que nous déclarons. Nous reviendrons sur ce sujet et vous apprendrez ce que _
représente généralement dans les prochains modules.