Menu

Int en string, string en int et conversion de types en Golang

Comment convertir entre types en Go : int en string et string en int avec strconv, flottants en entiers, conversions numériques avec T(v), octets et runes, le piège de string(65), et la gestion des erreurs de conversion.

Cette page contient des éditeurs exécutables - modifiez, exécutez et voyez la sortie instantanément.

Go ne convertit jamais les types implicitement. Vous convertissez entre types compatibles avec T(v), et entre nombres et texte avec le package strconv. Les deux conversions les plus recherchées :

strconv.Itoa (« integer to ASCII ») formate un int en texte décimal. strconv.Atoi (« ASCII to integer ») analyse du texte en int et renvoie une erreur quand le texte n'est pas un nombre valide. Vérifiez toujours cette erreur.

La conversion T(v)

La syntaxe de conversion de Go ressemble à un appel de fonction portant le nom du type cible. Elle fonctionne dans trois situations :

  1. entre types numériques (int, int64, float64, uint8, ...),
  2. entre string et []byte ou []rune,
  3. entre types qui partagent un type sous-jacent (Celsius et float64).

Lisez attentivement les résultats :

  • int(3.9) vaut 3 et int(-3.9) vaut -3. La conversion tronque vers zéro ; elle n'arrondit pas. Utilisez d'abord math.Round, math.Floor ou math.Ceil pour choisir le comportement. math.Round arrondit les demis en s'éloignant de zéro, donc -3.5 devient -4.
  • uint8(300) vaut 44, parce que seuls les 8 bits de poids faible survivent (300 moins 256), et int8(200) vaut -56 pour la même raison. Pas d'erreur, pas de panic.
  • Celsius et float64 partagent un type sous-jacent, donc ils se convertissent librement, mais seulement explicitement.

Les valeurs sont dans des variables exprès. Avec des constantes, les mêmes conversions ne compilent pas.

Les constantes sont vérifiées, les variables non

Convertir une constante qui ne tient pas dans le type est une erreur de compilation. Convertir une variable de même valeur reboucle silencieusement :

fmt.Println(uint8(300)) // compile error
x := 300
fmt.Println(uint8(x)) // 44
./main.go:6:20: constant 300 overflows uint8

Convertir une constante non entière vers un type entier est aussi refusé, alors que la même valeur dans une variable est tronquée :

./main.go:7:18: cannot convert -3.9 (untyped float constant) to type int

Si la valeur flottante est hors de la plage du type entier cible (par exemple int64(1e20)), le résultat dépend de l'implémentation : amd64 et arm64, par exemple, donnent des réponses différentes. Vérifiez la plage avant de convertir des valeurs non fiables.

Convertir des nombres en chaînes

DepuisFonctionExempleRésultat
intstrconv.Itoa(n)strconv.Itoa(-7)"-7"
int64strconv.FormatInt(n, base)strconv.FormatInt(255, 16)"ff"
uint64strconv.FormatUint(n, base)strconv.FormatUint(5, 2)"101"
float64strconv.FormatFloat(f, fmt, prec, 64)strconv.FormatFloat(3.14159, 'f', 2, 64)"3.14"
boolstrconv.FormatBool(b)strconv.FormatBool(true)"true"
n'importe quoifmt.Sprint(v)fmt.Sprint(3.5)"3.5"
n'importe quoi, formatéfmt.Sprintf(format, v)fmt.Sprintf("%05d", 42)"00042"

FormatFloat prend un octet de format ('f' pour la notation fixe, 'e' pour l'exposant, 'g' pour la plus courte des deux), une précision (-1 signifie « le moins de chiffres possible pour un aller-retour exact »), et la taille en bits du flottant d'origine (64 ou 32).

strconv est plus rapide que fmt.Sprint, qui emballe la valeur dans une interface et passe par le chemin de formatage général de fmt. Dans une boucle critique, cette différence se voit ; pour des conversions occasionnelles, prenez ce qui se lit le mieux.

Convertir des chaînes en nombres

VersFonctionRenvoie
intstrconv.Atoi(s)int, error
tout entier signéstrconv.ParseInt(s, base, bitSize)int64, error
tout entier non signéstrconv.ParseUint(s, base, bitSize)uint64, error
flottantstrconv.ParseFloat(s, bitSize)float64, error
boolstrconv.ParseBool(s)bool, error

ParseInt renvoie toujours un int64. L'argument bitSize (0, 8, 16, 32, 64) fixe la plage acceptée, donc le résultat est garanti de tenir quand vous le convertissez vers un type plus petit. Une base de 0 signifie « déduire du préfixe », donc 0x1f, 0o17, 0b101 et 1_000 sont tous analysés.

Ce que montre la sortie :

  • " 42" échoue. Atoi accepte un signe facultatif et des chiffres, rien d'autre. Une entrée lue avec bufio se termine généralement par \n, donc retirez-le.
  • "4.2" est invalide pour Atoi. Utilisez ParseFloat pour les décimaux.
  • Sur une erreur de dépassement, ParseInt renvoie la plus grande valeur qui tient (127 pour int8) avec l'erreur. N'utilisez pas la valeur quand l'erreur n'est pas nil.
  • Les erreurs sont des valeurs *strconv.NumError qui enveloppent strconv.ErrSyntax ou strconv.ErrRange, donc errors.Is peut les distinguer.

ParseBool accepte 1, t, T, TRUE, true, True et les formes fausses correspondantes. "yes" et "on" sont des erreurs.

Le piège de string(65)

Convertir un entier en string ne produit pas de chiffres. Cela produit le caractère de ce point de code Unicode :

n := 65
s := string(n) // "A", not "65"

Le compilateur l'accepte, mais go vet le signale :

./main.go:10:7: conversion from int to string yields a string of one rune, not a string of digits

Si vous voulez vraiment le caractère, dites-le avec une rune : string(rune(n)). Si vous voulez le nombre sous forme de texte, utilisez strconv.Itoa(n). Convertir une rune ou un byte en string est correct et courant :

Chaînes, octets et runes

string, []byte et []rune se convertissent les uns dans les autres avec T(v). Chaque conversion copie les données, parce que les chaînes sont immuables et que les slices ne le sont pas :

Convertissez en []rune quand vous devez indexer ou modifier par caractère ; convertissez en []byte pour les E/S, le hachage et les modifications au niveau des octets. La page runes et octets détaille l'UTF-8.

Conversion ou assertion de type

Une conversion fait passer une valeur d'un type concret à un autre. Récupérer la valeur concrète d'une interface (any, error, io.Reader) est une opération différente, l'assertion de type :

var v any = 42

n := v.(int)       // type assertion: v holds an int, give it to me
f := float64(n)    // conversion: int to float64
// f := float64(v) // compile error: cannot convert v (variable of interface type any)
//                  // to type float64: need type assertion

Faites d'abord l'assertion, puis convertissez. La forme comma-ok n, ok := v.(int) évite un panic quand le type est faux.

Référence rapide

TâcheCode
int en stringstrconv.Itoa(n)
int64 en stringstrconv.FormatInt(n, 10)
string en intn, err := strconv.Atoi(s)
string en int64n, err := strconv.ParseInt(s, 10, 64)
string en float64f, err := strconv.ParseFloat(s, 64)
float64 en stringstrconv.FormatFloat(f, 'f', -1, 64)
float64 en intint(f) (tronque) ou int(math.Round(f))
int en float64float64(n)
string en []byte[]byte(s)
[]byte en stringstring(b)
rune en stringstring(r)
bool en stringstrconv.FormatBool(b)
n'importe quelle valeur en stringfmt.Sprint(v)

Questions fréquentes

Comment convertir un int en string en Go ?

Utilisez strconv.Itoa(n) : strconv.Itoa(42) renvoie "42". Pour un int64, utilisez strconv.FormatInt(n, 10). fmt.Sprint(n) fonctionne aussi pour n'importe quel type mais il est plus lent. N'écrivez pas string(n) : cela traite n comme un point de code Unicode, donc string(65) vaut "A".

Comment convertir une string en int en Go ?

Utilisez strconv.Atoi, qui renvoie le nombre et une erreur :

n, err := strconv.Atoi("42")
if err != nil {
	// not a valid integer
}

Pour une taille ou une base précise, utilisez strconv.ParseInt(s, 10, 64), qui renvoie un int64. Atoi ne retire pas les espaces, donc " 42" est une erreur ; appelez d'abord strings.TrimSpace.

Comment faire un cast en Go ?

Go appelle cela une conversion, et la syntaxe est T(v) : float64(n), int(f), []byte(s). Elle fonctionne entre types numériques, entre chaînes et slices d'octets ou de runes, et entre types ayant le même type sous-jacent. Elle n'analyse pas du texte : transformer "42" en 42 demande strconv. Récupérer un type concret depuis une interface est une assertion de type, v.(T), pas une conversion.

Comment convertir un float en int en Go ?

int(f) tronque vers zéro : int(3.9) vaut 3 et int(-3.9) vaut -3. Pour arrondir, utilisez int(math.Round(f)). Si le flottant est hors de la plage du type entier, le résultat dépend de l'implémentation, donc vérifiez d'abord la plage quand la valeur vient d'une entrée.

Pourquoi string(65) renvoie-t-il « A » en Go ?

Convertir un entier en string l'interprète comme un point de code Unicode, et 65 est le point de code de A. go vet le signale : conversion from int to string yields a string of one rune, not a string of digits. Utilisez strconv.Itoa(65) pour obtenir "65".

Coddy programming languages illustration

Apprendre à coder avec Coddy

COMMENCER