ChatGPT解决这个技术问题 Extra ChatGPT

What is the difference between int and int64 in Go?

go

I have a string containing an integer (which has been read from a file).

I'm trying to convert the string to an int using strconv.ParseInt(). ParseInt requires that I provide a bitsize (bit sizes 0, 8, 16, 32, and 64 correspond to int, int8, int16, int32, and int64).

The integer read from the file is small (i.e. it should fit in a normal int). If I pass a bitsize of 0, however, I get a result of type int64 (presumably because I'm running on a 64-bit OS).

Why is this happening? How do I just get a normal int? (If someone has a quick primer on when and why I should use the different int types, that would awesome!)

Edit: I can convert the int64 to a normal int using int([i64_var]). But I still don't understand why ParseInt() is giving me an int64 when I'm requesting a bitsize of 0.

Use Atoi for brevity? Also, is your ParseInt function returning an error?
Okay, now I'm a little confused. If I use Atoi(), it gives me an int, and everything works. I was calling parseInt(s, 0, 0), which should infer base10 (since the string doesn't have a base prefix). However, Atoi is shorthand for calling parseInt w/ a base of 10. Why does the base parameter make a difference in the type returned?
The base parameter determines how the input string is read. A string might look like "123" or "0xBEEFCAKE" or "1011101" or "0677". All of which have a different meaning and yield a different numeric value. A base value of 0 means the code tries to figure this out by itself. But sometimes this is not possible. 11(decimal) vs 11 (binary) represent entirely different values.
Okay, I guess what I'm really confused about is the docs. The docs for Atoi say only that it's just a "shorthand for parseInt(s, 10, 0)". But why then does Atoi return int while parseInt return int64?
Not knowing exactly why, I will assume that Atoi was added simply to accommodate people who are more familiar with the C API: int atoi ( const char * str );

y
yanana
func ParseInt(s string, base int, bitSize int) (i int64, err error)

ParseInt always returns int64.

bitSize defines the range of values.

If the value corresponding to s cannot be represented by a signed integer of the given size, err.Err = ErrRange.

http://golang.org/pkg/strconv/#ParseInt

type int int

int is a signed integer type that is at least 32 bits in size. It is a distinct type, however, and not an alias for, say, int32.

http://golang.org/pkg/builtin/#int

So int could be bigger than 32 bit in the future or on some systems like int in C.

I guess on some systems int64 might be faster than int32 because that system only works with 64-bit integers.

Here is an example of an error when bitSize is 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)
}

In practice, Go usually uses int64 for int on an amd64 GOARCH and int32 for int on 32-bit GOARCHes. At least with the default compiler, I'm not sure about gccgo. So "int could be bigger than 32 bit..." isn't just speculation, it's actually rather likely since the 64-bit compilation targets are generally considered the main branch in Go.
"In practice, Go usually uses int64 for int on an amd64 [..]" - more precisely, int always equals the processor bit-size. So on 64 bit systems, it's 64 bit, on 32bit systems, it's 32 bit. I like to think it's either an alias of int32 or int64 depending on your compile target (even if it is not implemented as an alias, doesn't matter).
@zupa what is the source/reference for "int always equals the processor bit-size"?
p
peterSO

Package strconv func ParseInt func ParseInt(s string, base int, bitSize int) (i int64, err error) ParseInt interprets a string s in the given base (2 to 36) and returns the corresponding value i. If base == 0, the base is implied by the string's prefix: base 16 for "0x", base 8 for "0", and base 10 otherwise. The bitSize argument specifies the integer type that the result must fit into. Bit sizes 0, 8, 16, 32, and 64 correspond to int, int8, int16, int32, and int64. The errors that ParseInt returns have concrete type *NumError and include err.Num = s. If s is empty or contains invalid digits, err.Err = ErrSyntax; if the value corresponding to s cannot be represented by a signed integer of the given size, err.Err = ErrRange.

ParseInt always returns an int64 value. Depending on bitSize, this value will fit into int, int8, int16, int32, or int64. If the value cannot be represented by a signed integer of the size given by bitSize, then err.Err = ErrRange.

The Go Programming Language Specification Numeric types The value of an n-bit integer is n bits wide and represented using two's complement arithmetic. 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) There is also a set of predeclared numeric types with implementation-specific sizes: uint either 32 or 64 bits int same size as uint

int is either 32 or 64 bits, depending on the implementation. Usually it's 32 bits for 32-bit compilers and 64 bits for 64-bit compilers.

To find out the size of an int or uint, use strconv.IntSize.

Package strconv Constants const IntSize = intSize IntSize is the size in bits of an int or uint value.

For example,

package main

import (
    "fmt"
    "runtime"
    "strconv"
)

func main() {
    fmt.Println(runtime.Compiler, runtime.GOARCH, runtime.GOOS)
    fmt.Println(strconv.IntSize)
}

Output:

gc amd64 linux
64

j
jimt

strconv.ParseInt and friends return 64-bit versions to keep the API clean and simple. Else one would have to create separate versions for each possible return type. Or return interface{}, which would then have to go through a type assertion. None of which are ideal.

int64 is chosen, because it can hold any integer size up to, and including, the supported 64-bits. The bit size you pass into the function, ensures that the value is properly clamped to the correct range. So you can simply do a type conversion on the returned value, to turn it into whatever integer type you require.

As for the difference between int and int64, this is architecture-dependant. int is simply an alias for either a 32-bit or 64-bit integer, depending on the architecture you are compiling for.

For the discerning eye: The returned value is a signed integer. There is a separate strconv.ParseUint function for unsigned integers, which returns uint64 and follows the same reasoning as explained above.


From what I've seen so far, this is almost correct, except that I don't think int is simply an alias - it is in fact a distinct type. golang.org/pkg/builtin/#int
Indeed. Go doesn't really do type aliasing. Something like type int int32 is to be treated as a unique and separate type. Notably because it allows new functionality to be defined for the int type through the application of new methods.
M
Matt

For your purposes, strconv.Atoi() would be more convenient I think.

The other answers have been pretty exhaustive about explaining the int type, but I think a link to the Go language specification is merited here: http://golang.org/ref/spec#Numeric_types


I
Iftekhar Riyad

An int is the default signed type in go: it takes 32 bits (4 bytes) on a 32-bit machine and 64 bits(8 bytes) on a 64-bit machine. Reference- The way to go by Ivo Balbaert


U
Umar Hayat

In Go lang, each type is considered as separate data type which can not be used interchangeably with the base type. For example,

type CustomInt64 int64

In the above declaration, CustomInt64 and built-in int64 are two separate data types and cannot be used interchangeably.

The same is the case with int, int32, and int64, all of these are separate data types that can't be used interchangeably. Where int32 is 32 its integer type, int64 is 64 bits and the size of the generic int type is platform dependent. It is 32 bits wide on a 32-bit system and 64-bits wide on a 64-bit system. So we must be careful and specific while specifying generic data types like int, uint, and float. It may cause a problem somewhere in code and will crash application on a different platform.