Post

Go Constants and Type Coercion

Go Constants and Type Coercion

Typed Constants

The following code example makes a pretty trivial point about Go’s type system:

1
2
const foo int = 5
fmt.Printf("%g", foo)

Output: ./main.go:8:2: fmt.Printf format %g has arg foo of wrong type int

Obviously, the constant declaration specifies the type int and the usage of %g in the print statement assumes a float, which Go’s type system doesn’t like.

Untyped Constants

This example is more interesting:

1
2
3
4
5
const x = 3.14
var y float32 = x
var z float64 = x

fmt.Printf("%g %g", y, z)

Output: 3.14 3.14.

The constant x is not explicitly typed. It is a floating point constant (but not a specific type of floating point constant) at the point of declaration, because of the assigned value to the right of the = sign. The assignments to y and z insist on a float32 and a float64 respectively, so explicit typecasting is taking place here.

We can see a similar looking effect here:

1
2
3
4
const x = 3.14
a := func(b float64) float64 { return b }(x)

fmt.Printf("%g", a)

This code may look like a similar approach is being applied, but what we are really seeing here is parametric type coercion. The type specified in (b float64) is coercing the value 3.14 to be a float64. This kind of type coercion is rare in languages that don’t also have a dynamic typing feature set. You can find a further example in this post on Go Channel Directionality, where another little nugget of type coercion was uncovered.

More on Constants

The major types of literals in the Go language are:

  • rune
  • integer
  • floating-point
  • imaginary
  • string

In every case they can be assigned to variables and used as parameter values with behaviour exactly as we would reasonably expect. There are also cases where constant values don’t have to be hardcoded literals. The following code prints 2, for example:

1
2
3
4
5
const x = 1
const y = 2
const z = max(x, y)

fmt.Printf("%d", z)

Note the assignment to z does in fact work, but must be computable at compile time. The following code, however, will error:

1
2
3
const x = 1
var y = 2
const z = max(x, y)

Error: ./main.go:11:12: max(x, y) (value of type int) is not constant

Essentially, a constant doesn’t have to be a hard-coded literal, but it does at least have to be made of other constants.

Further Reading

Read more in the official Go documentation on constants.

This post is licensed under CC BY 4.0 by the author.