web-dev-qa-db-fra.com

Quelle est la différence entre int et int64 dans Go?

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.

72
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)
}
51
Shuriken

Package strconv

func ParseInt

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

Types numériques

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.

Package strconv

Constantes

const IntSize = intSize

IntSize est la taille en bits d'une valeur int ou uint.

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
25
peterSO

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.

5
jimt

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

5
Matt