我有一个包含整数的字符串(已从文件中读取)。
我正在尝试使用 strconv.ParseInt()
将 string
转换为 int
。 ParseInt
要求我提供位大小(位大小 0、8、16、32 和 64 对应于 int、int8、int16、int32 和 int64)。
从文件中读取的整数很小(即它应该适合正常的 int)。但是,如果我传递 0 的位大小,我会得到 int64
类型的结果(可能是因为我在 64 位操作系统上运行)。
为什么会这样?我怎样才能得到一个正常的int? (如果有人对我何时以及为什么应该使用不同的 int 类型有一个快速入门,那就太棒了!)
编辑:我可以使用 int([i64_var])
将 int64 转换为普通 int。但我仍然不明白为什么当我请求位大小为 0 时 ParseInt()
给了我一个 int64。
parseInt(s, 0, 0)
,它应该推断 base10(因为字符串没有基本前缀)。但是,Atoi 是调用 parseInt
w/ base 10 的简写。为什么 base 参数会影响返回的类型?
0
的基值意味着代码试图自己解决这个问题。但有时这是不可能的。 11
(十进制)与 11
(二进制)代表完全不同的值。
parseInt(s, 10, 0)
的简写”。但是为什么 Atoi 返回 int
而 parseInt
返回 int64?
Atoi
只是为了适应更熟悉 C API 的人:int atoi ( const char * str );
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)
}
包 strconv func ParseInt func ParseInt(s string, base int, bitSize int) (i int64, err error) ParseInt 解释给定基数(2 到 36)中的字符串 s 并返回相应的值 i。如果 base == 0,则字符串的前缀隐含了 base: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 = ErrSyntax;如果 s 对应的值不能用给定大小的有符号整数表示,则 err.Err = ErrRange。
ParseInt
始终返回 int64
值。根据 bitSize
,此值将适合 int
、int8
、int16
、int32
或 int64
。如果该值不能由 bitSize
给定大小的有符号整数表示,则为 err.Err = ErrRange
。
Go 编程语言规范 数字类型 n 位整数的值是 n 位宽,并使用二进制补码算法表示。 int8 所有有符号 8 位整数的集合(-128 到 127) int16 所有有符号 16 位整数的集合(-32768 到 32767) int32 所有有符号 32 位整数的集合(-2147483648 到 2147483647) int64所有有符号 64 位整数的集合(-9223372036854775808 到 9223372036854775807) 还有一组预先声明的具有特定于实现大小的数字类型: uint 32 位或 64 位 int 与 uint 大小相同
int
是 32 位或 64 位,具体取决于实现。通常 32 位编译器为 32 位,64 位编译器为 64 位。
要找出 int
或 uint
的大小,请使用 strconv.IntSize
。
包 strconv 常量 const IntSize = intSize IntSize 是 int 或 uint 值的位大小。
例如,
package main
import (
"fmt"
"runtime"
"strconv"
)
func main() {
fmt.Println(runtime.Compiler, runtime.GOARCH, runtime.GOOS)
fmt.Println(strconv.IntSize)
}
输出:
gc amd64 linux
64
strconv.ParseInt
和朋友返回 64 位版本以保持 API 简洁明了。否则,必须为每种可能的返回类型创建单独的版本。或者返回 interface{}
,然后必须通过类型断言。没有一个是理想的。
选择 int64
是因为它可以容纳任何整数大小,最高(包括)支持的 64 位。您传递给函数的位大小可确保将值正确限制在正确的范围内。因此,您可以简单地对返回值进行类型转换,将其转换为您需要的任何整数类型。
至于 int
和 int64
之间的区别,这是依赖于架构的。 int
只是 32 位或 64 位整数的别名,具体取决于您要编译的体系结构。
明眼人:返回值是有符号整数。对于无符号整数,有一个单独的 strconv.ParseUint
函数,它返回 uint64
并遵循与上述相同的推理。
int
只是一个别名——它实际上是一种不同的类型。 golang.org/pkg/builtin/#int
type int int32
之类的东西将被视为唯一且独立的类型。值得注意的是,它允许通过应用新方法为 int
类型定义新功能。
出于您的目的,我认为 strconv.Atoi()
会更方便。
关于解释 int
类型的其他答案非常详尽,但我认为这里值得链接到 Go 语言规范:http://golang.org/ref/spec#Numeric_types
在 Go 语言中,每种类型都被视为单独的数据类型,不能与基本类型互换使用。例如,
type CustomInt64 int64
在上述声明中,CustomInt64 和内置 int64 是两种独立的数据类型,不能互换使用。
int、int32 和 int64 也是如此,所有这些都是不能互换使用的独立数据类型。 int32 是 32 它的整数类型,int64 是 64 位,通用 int 类型的大小取决于平台。它在 32 位系统上为 32 位宽,在 64 位系统上为 64 位宽。因此,在指定 int、uint 和 float 等通用数据类型时,我们必须小心谨慎。它可能会导致代码中的某个地方出现问题,并使应用程序在不同的平台上崩溃。
int64
表示int
,在 32 位 GOARCH 上使用int32
表示int
。至少使用默认编译器,我不确定 gccgo。所以“int
可能大于 32 位......”不仅仅是推测,实际上很有可能,因为 64 位编译目标通常被认为是 Go 中的主要分支。