Untyped constants in Go

Michał Łowicki
golangspec
Published in
2 min readMar 19, 2020

Let’s start with quiz comparing two programs which differ only by single statement. Program C uses constant declaration (source code):

type N intfunc main() {
const c = 1
var n N = c
fmt.Println(n)
}

and program V uses variable declaration (source code):

type N intfunc main() {
var c = 1
var n N = c
fmt.Println(n)
}

Before scrolling down to see answers, please think for a moment about results of both C and V

.

.

.

.

.

.

.

Program C writes to stdout 1. The second one (V) might be a small surprise. It doesn’t build at all and gives compile-time error: cannot use c (type int) as type N in assignment. If you would like to understand what is exactly happening then just keep reading and in 2 minutes you’ll get it.

Constants in Go can be either typed or untyped. Untyped are created when constant declaration doesn’t specify type (source code):

const x float64 = 12
fmt.Printf("%T\n", x) // float64
const y = 12
fmt.Printf("%T\n", y) // int

Constant y is untyped. When printing its type we’re getting int though…

An untyped constant has a default type which is the type to which the constant is implicitly converted in contexts where a typed value is required.

For example default type for integer constant is int or it’s float64 for floating-point number.

In program V variable c is being set to untyped constant expression 1. Default type of integer constant is int so type of c is ultimately set to int — implicit conversion happens because variables always need to have a type (source code):

var c = 1
fmt.Println(reflect.TypeOf(c).Name()) // int

In program V while executing second assignment:

var n N = c

then assignability rules from language specification apply. Since n is of type N and c is of type int then we’ve a type mismatch and assignment statement is invalid. Why the program C works then? Because in that scenario c is an untyped constant and there is a dedicated assignability rule for such case:

x is assignable to T if x is an untyped constant representable by a value of type T.

👏👏👏 below to help others discover this story. Please follow me here or on Twitter if you want to get updates about new posts or boost work on future stories.

Resources

--

--

Michał Łowicki
golangspec

Software engineer at Datadog, previously at Facebook and Opera, never satisfied.