【问题标题】:What is the difference between int and int64 in Go?Go中的int和int64有什么区别?
【发布时间】:2014-02-24 19:43:17
【问题描述】:

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

我正在尝试使用strconv.ParseInt()string 转换为intParseInt 要求我提供位大小(位大小 0、8、16、32 和 64 对应于 int、int8、int16、int32 和 int64)。

从文件中读取的整数很小(即它应该适合正常的 int)。但是,如果我传递 0 的位大小,我会得到 int64 类型的结果(可能是因为我在 64 位操作系统上运行)。

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

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

【问题讨论】:

  • 为了简洁起见使用Atoi?另外,您的 ParseInt 函数是否返回错误?
  • 好的,现在我有点困惑。如果我使用 Atoi(),它会给我一个 int,并且一切正常。我打电话给parseInt(s, 0, 0),它应该推断出base10(因为字符串没有基本前缀)。但是,Atoi 是调用 parseInt 的简写,基数为 10。为什么 base 参数会影响返回的类型?
  • base 参数决定了如何读取输入字符串。字符串可能看起来像“123”或“0xBEEFCAKE”或“1011101”或“0677”。所有这些都有不同的含义并产生不同的数值。 0 的基值意味着代码试图自己解决这个问题。但有时这是不可能的。 11(十进制)与11(二进制)代表完全不同的值。
  • 好吧,我想我真正困惑的是文档。 Atoi 的文档只说它只是“parseInt(s, 10, 0) 的简写”。但是为什么 Atoi 返回 intparseInt 返回 int64?
  • 不知道具体原因,我假设添加 Atoi 只是为了适应更熟悉 C API 的人:int atoi ( const char * str );

标签: go


【解决方案1】:
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 位,或者在某些系统上,例如 C 语言中的 int

我猜在某些系统上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)
}

【讨论】:

  • 在实践中,Go 通常在 amd64 GOARCH 上使用 int64 表示 int,在 32 位 GOARCH 上使用 int32 表示 int。至少使用默认编译器,我不确定 gccgo。所以“int 可能大于 32 位...”不仅仅是推测,实际上很有可能,因为 64 位编译目标通常被认为是 Go 中的主要分支。
  • “在实践中,Go 通常在 amd64 [..] 上使用 int64 作为 int”-更准确地说,int 总是等于处理器位大小乙>。所以在 64 位系统上是 64 位,在 32 位系统上是 32 位。我喜欢认为它是 int32 或 int64 的别名,具体取决于您的编译目标(即使它没有作为别名实现,也没关系)。
  • @zupa “int 始终等于处理器位大小”的来源/参考是什么?
【解决方案2】:

Package strconv

func ParseInt

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

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

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

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

ParseInt 始终返回 int64 值。根据bitSize,此值将适合intint8int16int32int64。如果该值不能由bitSize 给出的大小的有符号整数表示,则err.Err = ErrRange

The Go Programming Language Specification

Numeric types

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 位。

要了解intuint 的大小,请使用strconv.IntSize

Package strconv

Constants

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

【讨论】:

    【解决方案3】:

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

    int64 被选中,因为它可以容纳任何整数大小,最高包括支持的 64 位。您传递给函数的位大小可确保将值正确限制在正确的范围内。因此,您可以简单地对返回的值进行类型转换,将其转换为您需要的任何整数类型。

    至于intint64 之间的区别,这是依赖于架构的。 int 只是 32 位或 64 位整数的别名,具体取决于您编译的架构。

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

    【讨论】:

    • 从我目前看到的情况来看,这几乎是正确的,除了我不认为int 只是一个别名——它实际上是一个不同的类型。 golang.org/pkg/builtin/#int
    • 确实如此。 Go 并没有真正做类型别名。 type int int32 之类的东西将被视为唯一且独立的类型。值得注意的是,它允许通过应用新方法为 int 类型定义新功能。
    【解决方案4】:

    出于您的目的,我认为strconv.Atoi() 会更方便。

    其他答案对于解释 int 类型非常详尽,但我认为此处值得提供指向 Go 语言规范的链接:http://golang.org/ref/spec#Numeric_types

    【讨论】:

      【解决方案5】:

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

      type CustomInt64 int64
      

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

      int、int32 和 int64 也是如此,所有这些都是独立的数据类型,不能互换使用。其中 int32 是 32 它的整数类型,int64 是 64 位,通用 int 类型的大小取决于平台。它在 32 位系统上为 32 位宽,在 64 位系统上为 64 位宽。因此,在指定通用数据类型(如 int、uint 和 float)时,我们必须小心且具体。它可能会导致代码中的某个地方出现问题,并且会导致其他平台上的应用程序崩溃。

      【讨论】:

        【解决方案6】:

        int 是 go 中默认的有符号类型:在 32 位机器上它需要 32 位(4 字节),在 64 位机器上需要 64 位(8 字节)。 参考-The way to go by Ivo Balbaert

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-07-30
          • 1970-01-01
          • 1970-01-01
          • 2010-09-12
          • 1970-01-01
          • 2020-05-05
          • 2015-11-04
          • 1970-01-01
          相关资源
          最近更新 更多