我对以下类型转换感到困惑。我预计这两种uint转换都会出现恐慌。
a := -1
_ = uint(a) // why no panic?
_ = uint(-1) // panics: constant -1 overflows uint
Run Code Online (Sandbox Code Playgroud)
为什么第 2 行没有恐慌?
正如第 6923 期所述:
T(c)其中T是类型并且c是常量意味着将其视为c具有类型T而不是默认类型之一。如果不能在 中表示,
它会给出一个错误,除了 for和常量,只要值不太大,我们就会悄悄舍入到该值。cTfloatcomplexT
这里:
const x uint = -1
var x uint = -1
Run Code Online (Sandbox Code Playgroud)
这不起作用,因为 -1 无法(隐式)转换为 uint。
_ = uint(a) // why no panic?
Run Code Online (Sandbox Code Playgroud)
因为a不是无类型常量,而是类型变量 ( int)。请参阅Playground和“ Golang 常量溢出 uint64 出了什么问题”:
package main
import "fmt"
func main() {
a := -1
_ = uint(a) // why no panic?
var b uint
b = uint(a)
fmt.Println(b)
// _ = uint(-1) // panics: main.go:7: constant -1 overflows uint
}
Run Code Online (Sandbox Code Playgroud)
结果:(4294967295在 32 位系统上)或18446744073709551615(在 64 位系统上),如starriet所评论
这是非常量数值转换的具体规则:
整数类型之间转换时,如果值为有符号整数,则符号扩展为隐式无限精度;否则为零扩展。
然后它被截断以适合结果类型的大小。