Go core · 3 MIN READ
Constants have no type until they need one
Explain why 1 << 40 compiles as a constant but overflows as an int32.
An untyped constant in Go has arbitrary precision and no type until it is used. const big = 1 << 62 is fine even where an int is 32 bits, because nothing has asked it to become an int yet. The moment it is assigned or passed, it takes the type it is needed as — and that is where it can fail to fit.
iota is the other half. Inside a const block it counts from zero, one step per line, which is how Go writes enumerations without an enum keyword. The idiom is worth recognising on sight: a type, a const block with iota, and often a String method.
SEE THE IDEA
A constant gets a type when the context asks
- 01
Exact constant
goconst limit = 1 << 40No machine-width integer yet
- 02
Typed context
govar n int64 = limitThe value must fit int64
- 03
Enumeration
goconst first = iotaiota advances per ConstSpec
Constant arithmetic is exact until a typed operation imposes a representation.
In practice
Use typed constants when a public API needs a particular type; keep untyped constants flexible when callers may use different numeric types. In a const block, iota counts specifications, including a blank-identifier specification. Several names on one specification share the same iota value.
Watch out
A constant can be valid by itself and still overflow the type of the variable or argument receiving it.
Read and predict
package main
import "fmt"
type Level int
const (
Debug Level = iota
Info
Warn
Error
)
func main() {
fmt.Println(Debug, Info, Warn, Error)
const big = 1 << 40
fmt.Println(big / 1024 / 1024 / 1024)
}What does this print?
Trace each value and write down your reasoning. Copy the source into GopherForge or your local Go environment to compile and check it. This web page does not execute your code or send it to a compiler service.
Progress stays in this browser. No account needed.