Tengo una cadena que contiene un número entero (que se ha leído de un archivo).
Estoy tratando de convertir el stringa un intusing strconv.ParseInt().  ParseIntrequiere que proporcione un tamaño de bits (los tamaños de bits 0, 8, 16, 32 y 64 corresponden a int, int8, int16, int32 e int64).
El entero leído del archivo es pequeño (es decir, debería caber en un int normal). Sin embargo, si paso un tamaño de bits de 0, obtengo un resultado de tipo int64(presumiblemente porque estoy ejecutando un sistema operativo de 64 bits).
¿Por qué está pasando esto? ¿Cómo obtengo un int normal? (Si alguien tiene una introducción rápida sobre cuándo y por qué debería usar los diferentes tipos de int, ¡sería increíble!)
Editar: puedo convertir el int64 a un int normal usando int([i64_var]). Pero todavía no entiendo por qué ParseInt()me da un int64 cuando solicito un tamaño de bits de 0.

parseInt(s, 0, 0), lo que debería inferir base10 (ya que la cadena no tiene un prefijo base). Sin embargo, Atoi es una forma abreviada de llamarparseIntcon una base de 10. ¿Por qué el parámetro base hace una diferencia en el tipo devuelto?0significa que el código intenta resolver esto por sí mismo. Pero a veces esto no es posible.11(decimal) vs11(binario) representan valores completamente diferentes.parseInt(s, 10, 0)". Pero, ¿por qué entonces Atoi regresaintmientrasparseIntregresa int64?Atoise agregó simplemente para adaptarse a las personas que están más familiarizadas con la API de C:int atoi ( const char * str );Respuestas:
func ParseInt(s string, base int, bitSize int) (i int64, err error)ParseInt siempre regresa
int64bitSizedefine rango de valores. Si el valor correspondiente as no puede ser representado por un entero con signo del tamaño dado, err.Err = ErrRange.http://golang.org/pkg/strconv/#ParseInt
type int intint es un tipo entero con signo que tiene al menos 32 bits de tamaño. Sin embargo, es un tipo distinto y no un alias para, digamos, int32.
http://golang.org/pkg/builtin/#int
Por
intlo tanto, podría ser mayor que 32 bits en el futuro o en algunos sistemas comointC.Supongo que en algunos sistemas
int64puede ser más rápidoint32porque ese sistema solo funciona con enteros de 64 bits.Aquí hay un ejemplo de error cuando
bitSizees 8http://play.golang.org/p/_osjMqL6Nj
package main import ( "fmt" "strconv" ) func main() { i, err := strconv.ParseInt("123456", 10, 8) fmt.Println(i, err) }fuente
int64forinten un GOARCH amd64 yint32parainten GOARCH de 32 bits. Al menos con el compilador predeterminado, no estoy seguro de gccgo. Entonces, "intpodría ser mayor que 32 bits ..." no es solo una especulación, en realidad es bastante probable ya que los objetivos de compilación de 64 bits generalmente se consideran la rama principal en Go.ParseIntsiempre devuelve unint64valor. En función debitSizeeste valor se ajusta aint,int8,int16,int32, oint64. Si el valor no puede ser representado por un entero con signo del tamaño dado porbitSize, entonceserr.Err = ErrRange.intes de 32 o 64 bits, según la implementación. Por lo general, es de 32 bits para compiladores de 32 bits y de 64 bits para compiladores de 64 bits.Para averiguar el tamaño de un
intouint, utilicestrconv.IntSize.Por ejemplo,
package main import ( "fmt" "runtime" "strconv" ) func main() { fmt.Println(runtime.Compiler, runtime.GOARCH, runtime.GOOS) fmt.Println(strconv.IntSize) }Salida:
gc amd64 linux 64fuente
strconv.ParseInty sus amigos regresan versiones de 64 bits para mantener la API limpia y simple. De lo contrario, habría que crear versiones independientes para cada posible tipo de devolución. O returninterface{}, que luego tendría que pasar por una aserción de tipo. Ninguno de los cuales es ideal.int64se elige porque puede contener cualquier tamaño de entero hasta, inclusive, los 64 bits admitidos. El tamaño de bit que pasa a la función garantiza que el valor se fije correctamente en el rango correcto. Entonces, simplemente puede hacer una conversión de tipo en el valor devuelto, para convertirlo en cualquier tipo de entero que necesite.En cuanto a la diferencia entre
intyint64, esto depende de la arquitectura.intes simplemente un alias para un entero de 32 bits o de 64 bits, según la arquitectura para la que está compilando.Para el ojo perspicaz: el valor devuelto es un entero con signo. Hay una
strconv.ParseUintfunción separada para enteros sin signo, que devuelveuint64y sigue el mismo razonamiento que se explicó anteriormente.fuente
intsea simplemente un alias, de hecho es un tipo distinto. golang.org/pkg/builtin/#inttype int int32debe tratarse como un tipo único y separado. Sobre todo porque permite definir nuevas funcionalidades para elinttipo mediante la aplicación de nuevos métodos.Para sus propósitos,
strconv.Atoi()creo que sería más conveniente.Las otras respuestas han sido bastante exhaustivas sobre la explicación del
inttipo, pero creo que se merece un enlace a la especificación del idioma Go aquí: http://golang.org/ref/spec#Numeric_typesfuente
En Go lang, cada tipo se considera un tipo de datos independiente que no se puede utilizar indistintamente con el tipo base. Por ejemplo,
type CustomInt64 int64En la declaración anterior, CustomInt64 e int64 integrado son dos tipos de datos separados y no se pueden usar indistintamente.
Lo mismo ocurre con int, int32 e int64, todos estos son tipos de datos separados que no se pueden usar indistintamente. Donde int32 es 32 su tipo entero, int64 es 64 bits y el tamaño del tipo int genérico depende de la plataforma. Tiene 32 bits de ancho en un sistema de 32 bits y 64 bits de ancho en un sistema de 64 bits. Por lo tanto, debemos ser cuidadosos y específicos al especificar tipos de datos genéricos como int, uint y float. Puede causar un problema en algún lugar del código y bloquear la aplicación en una plataforma diferente.
fuente