Go中int和int64有什么区别?


86

我有一个包含整数的字符串(已从文件中读取)。

我正在尝试将转换stringintusing strconv.ParseInt()ParseInt要求我提供一个位大小(位大小0、8、16、32和64分别对应于int,int8,int16,int32和int64)。

从文件读取的整数很小(即,它应该适合普通的int)。但是,如果传递的位大小为0,则会得到类型的结果int64(大概是因为我正在64位OS上运行)。

为什么会这样呢?我怎样才能得到一个普通的整数?(如果有人快速入门了何时以及为什么我应该使用不同的int类型,那真是太棒了!)

编辑:我可以使用将int64转换为普通int int([i64_var])。但是我仍然不明白为什么ParseInt()当我请求位大小为0时为什么给我一个int64。


2
为简便起见,请使用Atoi吗?另外,您的ParseInt函数是否返回错误?
马特

2
好吧,现在我有点困惑。如果我使用Atoi(),它将为我提供一个整数,并且一切正常。我正在调用parseInt(s, 0, 0),它应该推断base10(因为字符串没有基本前缀)。但是,Atoi是调用parseIntw /以10为底的简写形式。为什么base参数在返回的类型上有所不同?
艾萨克·唐特·林德尔

基本参数确定如何读取输入字符串。字符串可能看起来像“ 123”或“ 0xBEEFCAKE”或“ 1011101”或“ 0677”。所有这些都有不同的含义并产生不同的数值。基值0表示代码试图自行解决。但这有时是不可能的。11(十进制)与11(二进制)表示完全不同的值。
2014年

1
好的,我想我真正感到困惑的是文档。Atoi的文档只说这只是“的简写parseInt(s, 10, 0)”。但是为什么AtoiintparseInt返回int64的同时返回?
艾萨克·唐特·林德尔

1
不知道确切的原因,我想Atoi添加它只是为了容纳对C API更熟悉的人:int atoi ( const char * str );
jimt 2014年

Answers:


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

ParseInt总是返回 int64

bitSize定义值的范围。如果与s对应的值不能用给定大小的有符号整数表示,则err.Err = ErrRange。

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

type int int

int是有符号整数类型,其大小至少为32位。但是,它是一个独特的类型,而不是int32的别名。

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

因此int将来可能会大于32位,或者int在C等某些系统上会大于32位。

我猜在某些系统上int64可能会比int32该系统更快,因为该系统仅适用于64位整数。

bitSize是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)
}

22
在实践中,围棋通常使用int64int上AMD64 GOARCH并int32int32位GOARCHes。至少对于默认的编译器,我不确定gccgo。因此,“int可能大于32位...”不仅仅是猜测,实际上很可能是因为64位编译目标通常被视为Go中的主要分支。
LinearZoetrope 2014年

12
“实际上,Go通常在amd64 [..]上将int64用作int”-更准确地说,int始终等于处理器的bit-size。因此,在64位系统上,它是64位,在32位系统上,它是32位。我喜欢认为它是int32或int64的别名,具体取决于您的编译目标(即使未将其实现为别名也没关系)。
zupa 2015年

@zupa“ int始终等于处理器的位大小”的来源/参考是什么?
kapad

29

软件包strconv

func ParseInt

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

ParseInt解释给定基数(2到36)中的字符串s并返回对应的值i。如果base == 0,则字符串的前缀隐含基数:“ 0x”的基数为16,“ 0”的基数为8,否则为10。

bitSize参数指定结果必须适合的整数类型。位大小0、8、16、32和64分别对应于int,int8,int16,int32和int64。

ParseInt返回的错误的具体类型为* NumError,其中包括err.Num = s。如果s为空或包含无效数字,则err.Err = ErrSyntax; 如果与s对应的值不能用给定大小的有符号整数表示,则err.Err = ErrRange。

ParseInt总是返回一个int64值。根据bitSize,该值将适用于intint8int16int32,或int64。如果该值不能由给出的大小的有符号整数表示bitSize,则err.Err = ErrRange

Go编程语言规范

数值类型

一个n位整数的值是n位宽,并使用二进制补码算术表示。

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)

还有一组预先声明的数字类型,具有特定于实现的大小:

uint     either 32 or 64 bits
int      same size as uint

int是32位还是64位,具体取决于实现方式。对于32位编译器,通常为32位;对于64位编译器,通常为64位。

要找出intor的大小uint,请使用strconv.IntSize

软件包strconv

常数

const IntSize = intSize

IntSizeintuint值的大小(以位为单位)。

例如,

package main

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

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

输出:

gc amd64 linux
64

7

strconv.ParseInt和朋友返回64位版本,以保持API的简洁明了。否则,将不得不为每种可能的返回类型创建单独的版本。或return interface{},然后必须进行类型断言。没有一个是理想的。

int64之所以选择,是因为它可以容纳最大整数,包括支持的64位。传递给函数的位大小可确保将值正确钳位在正确的范围内。因此,您只需对返回值进行类型转换,即可将其转换为所需的任何整数类型。

至于int和之间的区别int64,这取决于体系结构。int只是32位或64位整数的别名,具体取决于要编译的体系结构。

对于有眼识的人:返回的值是一个有符号整数。strconv.ParseUint对于无符号整数,有一个单独的函数,该函数返回uint64并遵循与上述相同的推理。


4
从目前为止我所看到的,这几乎是正确的,只是我不认为int这只是一个别名-实际上它是一个独特的类型。golang.org/pkg/builtin/#int
艾萨克Dontje林德尔

确实。Go并不会真正执行类型别名。类似的东西type int int32将被视为唯一且独立的类型。尤其是因为它允许int通过应用新方法来为类型定义新功能。
2014年


0

在Go lang中,每种类型都被视为单独的数据类型,不能与基本类型互换使用。例如,

type CustomInt64 int64

在上面的声明中,CustomInt64和内置的int64是两个单独的数据类型,不能互换使用。

int,int32和int64的情况相同,所有这些都是单独的数据类型,不能互换使用。在int32是32的整数类型的情况下,int64是64位,泛型int类型的大小取决于平台。在32位系统上,它的宽度为32位,在64位系统上,它的宽度为64位。因此,在指定诸如int,uint和float之类的通用数据类型时,我们必须小心谨慎。这可能会在代码中的某处引起问题,并使其他平台上的应用程序崩溃。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.