Constants can be confusing and easy to misuse in Go if you are coming from an untyped language. In this article we will learn what constants are, and when it is best to make use of them.
Most of the points I make here apply to general-purpose programming languages as a whole, but by focusing specifically on Go we can dive a bit deeper and come up with some good rules of thumb.
Go > Javascript
Many languages have constants, typically denoted by the keyword const.
In go and javascript alike they are declared as such:
const frameRate = 60
The interesting thing about constants in Go is that they:
By contrast, in javascript they:
Constants in Go must be assigned before the program runs, that is, when the program compiles using go build. Constants can rely on the value of other constants, but not on runtime calculations. For example:
const seconds = 120
const minutes = seconds / 60
Is fine because both values can be known before the program runs. The following will not work:
func addMinutes(minutes int) {
const more = minutes + 60
return more
}
This won't work because "more" relies on a runtime variable, "minutes". Keep in mind that this would work in javascript, because the only rule with constants in javascript is that they can't be re-assigned.
The Go compiler doesn't need to worry about a constant changing its value, so it can swap every instance of the const with an unchanging number. This makes constants slightly faster.
Numeric, boolean, and string types can all be made constant. This includes things like runes, floats, integers, and even custom types that are based on valid underlying types. For example:
type myString string
const lane myString = "wagslane"
Other types like arrays, slices, and maps can not be declared as constant. This makes sense because those types are essentially just pointers, which are addresses of mutable data.
By contrast, in javascript anything can be made constant. Arrays can be constant, and an array can have its elements mutated, or it can be enlarged or shrunk. The only safety the const provides is that the variable can't be explicitly reassigned.
In Go, variables can have their typed inferred:
thisIsAString := "wagslane"
Constants, on the other hand, get an untyped flag
const thisIsAnUntypedString = "wagslane"
An untyped string behaves mostly like a string. That is, its a string type, but doesn't have a Go value of type string. In order to give it the official Go type of string, it must be declared:
const thisIsATypedString string = "wagslane"
To read more about untyped constants checkout:
https://blog.golang.org/constants#TOC_4.
Anything that can be a constant should be a constant. By declaring a variable constant you get the following benefits:
Additionally, constants don't follow the same rule of thumb that normal variables do when being declared in the global scope. There is nothing wrong with declaring global constants. Granted, if the constant is only used in one place, it may make sense to declare it there. The point however remains: it isn't dangerous to declare constants globally.
The danger of global variables is obvious: if you create a global variable then all functions using that variable become stateful. Each invocation of that function has the potential to behave differently.
Hopefully this helps you understand a bit more about constants and when to use them. Thanks for reading!
Previously published at https://qvault.io/2019/10/14/constants-in-go-vs-javascript-and-when-to-use-them/