J'ai une chaîne contenant un entier (qui a été lu dans un fichier).
J'essaie de convertir le string
en un int
en utilisant strconv.ParseInt()
. ParseInt
nécessite que je fournisse une taille de bit (les tailles de bits 0, 8, 16, 32 et 64 correspondent à int, int8, int16, int32 et int64).
Le nombre entier lu dans le fichier est petit (c’est-à-dire qu’il devrait tenir dans un int normal). Si je passe une taille de bit de 0, cependant, j'obtiens un résultat de type int64
(Probablement parce que je suis sous un système d'exploitation 64 bits).
Pourquoi cela arrive-t-il? Comment puis-je obtenir un int normal? (Si quelqu'un a un aperçu rapide du moment et des raisons pour lesquelles je devrais utiliser les différents types int, ce serait génial!)
Edit: Je peux convertir l’int64 en int normal avec int([i64_var])
. Mais je ne comprends toujours pas pourquoi ParseInt()
me donne un int64 alors que je demande une taille de bit de 0.
func ParseInt(s string, base int, bitSize int) (i int64, err error)
ParseInt renvoie toujours int64
bitSize
définit la plage de valeurs. Si la valeur correspondant à s ne peut pas être représentée par un entier signé de la taille donnée, err.Err = ErrRange.
http://golang.org/pkg/strconv/#ParseInt
type int int
int est un type entier signé dont la taille est d'au moins 32 bits. C'est un type distinct, cependant, et non un alias pour, disons, int32.
http://golang.org/pkg/builtin/#int
Donc, int
pourrait être plus grand que 32 bits dans le futur ou sur certains systèmes comme int
en C.
Je suppose que sur certains systèmes int64
pourrait être plus rapide que int32
parce que ce système ne fonctionne qu'avec des entiers 64 bits.
Voici un exemple d'erreur lorsque bitSize
vaut 8
http://play.golang.org/p/_osjMqL6Nj
package main
import (
"fmt"
"strconv"
)
func main() {
i, err := strconv.ParseInt("123456", 10, 8)
fmt.Println(i, err)
}
func ParseInt(s string, base int, bitSize int) (i int64, err error)
ParseInt interprète une chaîne s dans la base donnée (2 à 36) et renvoie la valeur correspondante i. Si base == 0, la base est impliquée par le préfixe de la chaîne: base 16 pour "0x", base 8 pour "0" et base 10 sinon.
L'argument bitSize spécifie le type entier dans lequel le résultat doit être contenu. Les tailles de bits 0, 8, 16, 32 et 64 correspondent à int, int8, int16, int32 et int64.
Les erreurs renvoyées par ParseInt ont un type concret * NumError et incluent err.Num = s. Si s est vide ou contient des chiffres non valides, err.Err = ErrSyntax; si la valeur correspondant à s ne peut pas être représentée par un entier signé de la taille donnée, err.Err = ErrRange.
ParseInt
retourne toujours un int64
valeur. Selon bitSize
, cette valeur tiendra dans int
, int8
, int16
, int32
, ou int64
. Si la valeur ne peut pas être représentée par un entier signé de la taille donnée par bitSize
, alors err.Err = ErrRange
.
Spécification du langage de programmation Go
La valeur d'un entier de n bits a une largeur de n bits et est représentée à l'aide de l'arithmétique des complément à deux.
int8 the set of all signed 8-bit integers (-128 to 127) int16 the set of all signed 16-bit integers (-32768 to 32767) int32 the set of all signed 32-bit integers (-2147483648 to 2147483647) int64 the set of all signed 64-bit integers (-9223372036854775808 to 9223372036854775807)
Il existe également un ensemble de types numériques prédéclarés avec des tailles spécifiques à l'implémentation:
uint either 32 or 64 bits int same size as uint
int
vaut 32 ou 64 bits, selon l'implémentation. Il s'agit généralement de 32 bits pour les compilateurs 32 bits et de 64 bits pour les compilateurs 64 bits.
Pour connaître la taille d'un int
ou uint
, utilisez strconv.IntSize
.
const IntSize = intSize
IntSize
est la taille en bits d'une valeurint
ouuint
.
Par exemple,
package main
import (
"fmt"
"runtime"
"strconv"
)
func main() {
fmt.Println(runtime.Compiler, runtime.GOARCH, runtime.GOOS)
fmt.Println(strconv.IntSize)
}
Sortie:
gc AMD64 linux
64
strconv.ParseInt
et amis renvoient des versions 64 bits pour que l'API reste simple et propre. Sinon, il faudrait créer des versions distinctes pour chaque type de retour possible. Ou retourner interface{}
, qui devrait alors passer par une assertion de type. Aucun de ceux qui sont idéaux.
int64
est choisi, car il peut contenir n'importe quelle taille entière, y compris les 64 bits pris en charge. La taille de bit que vous transmettez à la fonction garantit que la valeur est correctement fixée à la plage correcte. Ainsi, vous pouvez simplement faire une conversion de type sur la valeur renvoyée pour la convertir en tout type d’entier requis.
Quant à la différence entre int
et int64
, cela dépend de l’architecture. int
est simplement un alias pour un entier 32 bits ou 64 bits, selon l'architecture pour laquelle vous compilez.
Pour l'œil averti: la valeur renvoyée est un entier signé. Il y a un strconv.ParseUint
fonction pour les entiers non signés, qui retourne uint64
et suit le même raisonnement que celui expliqué ci-dessus.
Pour vos besoins, strconv.Atoi()
serait plus pratique, je pense.
Les autres réponses ont été assez exhaustives pour expliquer le type int
, mais je pense qu’un lien vers la spécification du langage Go est mérité ici: http://golang.org/ref/spec#Numeric_types