Typed Constants
The following code example illustrates a trivial point about Go’s type system:
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:
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:
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:
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:
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.