英文:
No panic when converting int to uint?
问题
我对以下类型转换感到困惑。我本来期望两个uint
转换都会引发恐慌。
a := -1
_ = uint(a) // 为什么没有恐慌?
_ = uint(-1) // 引发恐慌:常量-1溢出uint
为什么第2行没有引发恐慌?
链接:https://play.golang.org/p/jcfDL8km2C
英文:
I'm confused about the following type conversion. I would expect both uint
conversions to panic.
a := -1
_ = uint(a) // why no panic?
_ = uint(-1) // panics: constant -1 overflows uint
Why doesn't it panic in line 2?
答案1
得分: 5
如在问题 6923中提到:
> T(c)
,其中T
是一个类型,c
是一个常量,意味着将c
视为具有类型T
而不是默认类型之一。如果c
无法表示为T
,则会报错,但对于float
和complex
常量,只要值不太大,我们会将其静默舍入为T
。
在这里:
const x uint = -1
var x uint = -1
> 这不起作用,因为-1不能(隐式地)**转换**为uint。
_ = uint(a) // 为什么没有恐慌?
因为a
不是无类型常量,而是一个有类型的变量(int
)。请参见Playground和“Golang常量溢出uint64有什么问题”:
package main
import "fmt"
func main() {
a := -1
_ = uint(a) // 为什么没有恐慌?
var b uint
b = uint(a)
fmt.Println(b)
// _ = uint(-1) // 恐慌:main.go:7: constant -1 overflows uint
}
结果:在32位系统上为4294967295
,在64位系统上为18446744073709551615
,由starriet在评论中注释。
这是非常量数值转换的特定规则:
> 在整数类型之间进行转换时,如果值是有符号整数,则将其符号扩展为隐式无限精度;否则将其零扩展。然后将其截断以适应结果类型的大小。
英文:
As mentioned in issue 6923:
> T(c)
where T
is a type and c
is a constant means to treat c
as having type T
rather than one of the default types.
It gives an error if c
can not be represented in T
, except that for float
and complex
constants we quietly round to T
as long as the value is not too large.
Here:
const x uint = -1
var x uint = -1
> This doesn't work because -1 cannot be (implicitly) converted to a uint.
_ = uint(a) // why no panic?
Because a
is not an untyped constant, but a typed variable (int
). See Playground and "what's wrong with Golang constant overflows 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
}
Result: 4294967295
(on 32-bits system) or 18446744073709551615
(on 64-bits system), as commented by starriet
That are specific rules for the conversion of non-constant numeric values:
> When converting between integer types, if the value is a signed integer, it is sign extended to implicit infinite precision; otherwise it is zero extended.
It is then truncated to fit in the result type's size.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论