Untyped constants in Go
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 toT
ifx
is an untyped constant representable by a value of typeT
.
👏👏👏 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.