We’ve learned about types, type identity, and type assignability. But you may recall a bit of a discussion about some of the esoteric features of constants in Go. Namely, they can be untyped, and they don’t overflow. So how do we know if a constant can be represented faithfully by a particular type?
We finally have the answer, in all its detailed glory:
Representability
A constant
x
is representable by a value of typeT
, whereT
is not a type parameter, if one of the following conditions applies:
x
is in the set of values determined byT
.T
is a floating-point type andx
can be rounded toT
’s precision without overflow. Rounding uses IEEE 754 round-to-even rules but with an IEEE negative zero further simplified to an unsigned zero. Note that constant values never result in an IEEE negative zero, NaN, or infinity.T
is a complex type, andx
’s componentsreal(x)
andimag(x)
are representable by values ofT
’s component type (float32
orfloat64
).If
T
is a type parameter,x
is representable by a value of typeT
ifx
is representable by a value of each type inT
’s type set.x T x is representable by a value of T because 'a' byte 97 is in the set of byte values 97 rune rune is an alias for int32, and 97 is in the set of 32-bit integers "foo" string "foo" is in the set of string values 1024 int16 1024 is in the set of 16-bit integers 42.0 byte 42 is in the set of unsigned 8-bit integers 1e10 uint64 10000000000 is in the set of unsigned 64-bit integers 2.718281828459045 float32 2.718281828459045 rounds to 2.7182817 which is in the set of float32 values -1e-1000 float64 -1e-1000 rounds to IEEE -0.0 which is further simplified to 0.0 0i int 0 is an integer value (42 + 0i) float32 42.0 (with zero imaginary part) is in the set of float32 values
x T x is not representable by a value of T because 0 bool 0 is not in the set of boolean values 'a' string 'a' is a rune, it is not in the set of string values 1024 byte 1024 is not in the set of unsigned 8-bit integers -1 uint16 -1 is not in the set of unsigned 16-bit integers 1.1 int 1.1 is not an integer value 42i float32 (0 + 42i) is not in the set of float32 values 1e1000 float64 1e1000 overflows to IEEE +Inf after rounding
Quotes from The Go Programming Language Specification Version of December 15, 2022