将int转换为uint时不会出现问题。

huangapple go评论73阅读模式
英文:

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?

https://play.golang.org/p/jcfDL8km2C

答案1

得分: 5

如在问题 6923中提到:

> T(c),其中T是一个类型,c是一个常量,意味着将c视为具有类型T而不是默认类型之一。如果c无法表示为T,则会报错,但对于floatcomplex常量,只要值不太大,我们会将其静默舍入为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.

huangapple
  • 本文由 发表于 2017年1月29日 14:21:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/41918232.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定