golang常量溢出uint64有什么问题

what's wrong with golang constant overflows uint64

userid := 12345
did := (userid & ^(0xFFFF << 48))

编译这段代码时,我得到:

./xxxx.go:511: constant -18446462598732840961 overflows int

你知道这是怎么回事吗?如何解决? 谢谢

The Go Programming Language Specification

Constants

Numeric constants represent values of arbitrary precision and do not overflow.

Constants may be typed or untyped.

A constant may be given a type explicitly by a constant declaration or conversion, or implicitly when used in a variable declaration or an assignment or as an operand in an expression. It is an error if the constant value cannot be represented as a value of the respective type.

An untyped constant has a default type which is the type to which the constant is implicitly converted in contexts where a typed value is required, for instance, in a short variable declaration such as i := 0 where there is no explicit type. The default type of an untyped constant is bool, rune, int, float64, complex128 or string respectively, depending on whether it is a boolean, rune, integer, floating-point, complex, or string constant.

Numeric types

int is an implementation-specific size, either 32 or 64 bits.

useridint 类型。例如,

package main

import "fmt"

func main() {
    userid := 12345
    did := uint64(userid) & ^uint64(0xFFFF<<48)
    fmt.Println(userid, did)
}

输出:

12345 12345

^(0xFFFF << 48)是一个无类型常量,在go中是一个任意大的值。

0xffff << 480xffff000000000000。当你否定它时,你得到 -0xffff000000000001 (因为有二进制补码,-x = ^x + 1,或 ^x = -(x + 1))。

当你写 userid := 12345 时,userid 得到类型 int。然后,当您尝试使用无类型常量 -0xffff000000000001 和 (&) 时,编译器认为该常量需要是 int。此时,编译器会报错,因为该值的数量级太大,无法成为 int.

如果您尝试获取常量 0x0000ffffffffffff,那么您可以使用 1<<48 - 1,它(如果您有 64 位整数)将适合。由于如果 int 是 32 位,您的代码将永远无法工作,那么您可能应该在代码中使用 int64 而不是 int 以使其可移植。

博客 post https://blog.golang.org/constants 解释了常量的工作原理,以及它们为何如此的一些背景知识。