为什么不能将 int64 的最小值存储到 uint64 中?

per*_*ter 1 go

理论上,int64适合uint64,当然它们的数值会有所不同,因为第一位是为int64上的符号保留的,但是为什么我不能进行这种转换?这对我来说似乎是有效的

import (
    "fmt"
    "math"
)

func main() {
    var randomNum uint64 = math.MinInt64
    fmt.Println(randomNum)
}
Run Code Online (Sandbox Code Playgroud)

产生错误

constant -9223372036854775808 overflows uint64

Run Code Online (Sandbox Code Playgroud)

从技术上讲,math.MinInt64这是-9223372036854775808一个适合 63 位加号的数字。

我主要研究这个,因为我想转换8 bytes回具有正确符号的 int64,但到目前为止我只看到返回的函数uint64

binary.LittleEndian.Uint64(bytesArrays[0:8])
Run Code Online (Sandbox Code Playgroud)

Gas*_*lth 6

int64 确实适合 uint64,但这不是问题中的代码的作用。该代码将常量 math.MinInt64 分配给 uint64 变量randomNum。编译器报告错误,因为该常量无法用 uint64表示。

首先分配给变量,以便常量的规则不适用:

x := int64(math.MinInt64)
var randomNum = uint64(x)
fmt.Println(randomNum)
Run Code Online (Sandbox Code Playgroud)


Hym*_*sco 6

这种“转换”不起作用的原因是你的程序中没有转换。赋值不会隐式执行转换(接口类型除外)。

请参阅管理常量值分配的可分配性规则:

如果满足以下条件之一,则值 x 可分配给 T 类型的变量(“x 可分配给 T”):

  • x 的类型与 T 相同。
  • ...
  • x 是一个无类型常量,可由类型 T 的值表示。

在本例中,math.MinInt64是一个无类型常量,但它不能用 type 的值表示uint64,因为它的定义如下:

uint64 所有无符号 64 位整数的集合(0 到 18446744073709551615)

负 64 位整数和无符号 64 位整数之间的转换是可能的,但您需要进行真正的转换。然而,由于熟悉的规则,您仍然无法直接转换常量值:

如果 x 可以用 T 的值表示,则常量值 x 可以转换为类型 T。

所以,正确的方法是首先将数字赋给一个非常量值:

x := int64(math.MinInt64)
y := uint64(x)
fmt.Println(y)
Run Code Online (Sandbox Code Playgroud)

游乐场链接