Constants
const, iota, typed vs untyped constants, and constant expressions evaluated at compile time.
Constants in Go are values computed at compile time. They can be boolean, numeric, or string. Unlike variables, constants cannot be assigned to at runtime - the compiler enforces this.
const declares a single value or a block of values. Constants must be assignable from a literal or a constant expression.
package main
import "fmt"
const Pi = 3.14159
const MaxRetries = 3
const ServiceName = "auth-service"
func main() {
fmt.Println(Pi, MaxRetries, ServiceName)
const localTimeout = 30 // constants can be declared inside functions too
fmt.Println(localTimeout)
}iota is a compile-time counter that resets to 0 at the start of each const block and increments by 1 for each constant. It is the idiomatic way to define enumerations in Go.
package main
import "fmt"
type Direction int
const (
North Direction = iota // 0
East // 1
South // 2
West // 3
)
type ByteSize float64
const (
_ = iota // ignore first value by assigning to blank identifier
KB ByteSize = 1 << (10 * iota) // 1024
MB // 1048576
GB // 1073741824
)
func main() {
fmt.Println(North, East, South, West)
fmt.Println(KB, MB, GB)
}An untyped constant has no explicit type - it adopts a default type at the point of use. A typed constant carries its type and will only satisfy type-safe comparisons.
package main
import "fmt"
const untypedMax = 1000 // untyped int constant
const typedMax int32 = 1000 // typed int32 constant
func printInt64(n int64) {
fmt.Println(n)
}
func main() {
printInt64(untypedMax) // OK - untyped constant is widened to int64
// printInt64(typedMax) // compile error: cannot use typedMax (int32) as int64
_ = typedMax
}In production
Untyped integer constants are assigned a default type (int) at the point of use - passing one across a package boundary can produce surprising implicit widening or narrowing depending on the target platform's int size (32 vs 64 bits). Typed constants make intent explicit and prevent cross-package confusion. This matters especially for constants used as sizes, capacities, or enum discriminants that flow into serialization formats or database columns where the width is load-bearing.
Enjoyed this? Get more essays on software craft delivered to your inbox.
Subscribe free