We're sorry but this app doesn't work properly without JavaScript enabled. Please enable it to continue.

Constants in Go

Lane Wagner
Lane WagnerBoot.dev co-founder and backend engineer

Last published

Table of Contents

Constants can be confusing and easy to misuse in Go if you are coming from an untyped language. Let's take a look at some of the nuanced details of how they work in Go. It's probably unsurprising, but Go's constants are almost nothing like JavaScript's bastardized version of the concept.

All the content from our Boot.dev courses are available for free here on the blog. This one is the "Constants and Formatting" chapter of Learn Go. If you want to try the far more immersive version of the course, do check it out!

Declaring Constants

Constants are declared with the const keyword. They can't use the := short declaration syntax.

const pi = 3.14159

Constants can be primitive types like strings, integers, booleans and floats. They cannot be more complex types like slices, maps and structs.

As the name implies, the value of a constant can't be changed after it has been declared.

Go vs JavaScript

Many programming languages support constants, often denoted by the keyword const.

Go and JavaScript both declare new constants in the same way:

const frameRate = 60

Constants in Go

  • Must be able to be assigned at compile time. The value of a const can't be the result of a runtime calculation
  • Run faster because the compiler can make specific optimizations
  • Cannot change. The compiler will not allow them to be re-assigned
  • Only work with some types. Arrays, Slices, Maps, Structs, etc... can't be made constant (or can they?)
  • Are not normal Go types unless explicitly assigned as such

Constants in JavaScript

  • Can't be reassigned, but can change. JavaScript's constants are extremely misleading. the const keyword does NOT define a constant value. It defines a constant reference to a value.
  • If the constant is a type that has inner workings that change, like an array or object then the inner references can be changed.
  • Can be assigned using calculated values at runtime, but can't be re-assigned.

The takeaway if you are coming from JavaScript is that Go's constants are just different. They deal with compile-time values, not immutable naming.

In Go, constants provide complete safety in regard to the value they hold: they're guaranteed to always reference the same value.

In JavaScript, all a const does is ensure that the same name can't be changed to reference a different variable in the same scope.

Computed Constants

Constants must be known at compile time. They are usually declared with a static value:

const myInt = 15

However, constants can be computed as long as the computation can happen at compile time.

For example, this is valid:

const firstName = "Lane"
const lastName = "Wagner"
const fullName = firstName + " " + lastName

That said, you cannot declare a constant that can only be computed at run-time like you can in JavaScript. This breaks:

// the current time can only be known when the program is running
const currentTime = time.Now()

Constants Are Faster

The Go compiler doesn't need to worry about a const changing its value, so it can swap every instance of the const with an unchanging number. This makes constants slightly faster.

Numeric Constants are Just Numbers

Numeric constants can be much larger and have much greater precision than normal variables because they have arbitrary-precision. When numeric constants are assigned to a variable they must be able to fit the size of the type they are being assigned to. Take a look at the following examples:

const large = 1e10000
const E = 2.71828182845904523536028747135266249775724709369995957496696763

The large number can't be printed, but we can still use it in a calculation:

fmt.Println(large) // won't compile

small := (large / 1e9999) // works as expected
fmt.Println(small) // prints 10

High-precision floating point numbers like E can still be used but the high precision is lost when assigned to a float64 or float32.

e := math.E
fmt.Println(e)
// prints 2.718281828459045

Declare Multiple Constants as a Block

const (
	pi = 3.14
	timeout = 120 * time.Second
	maxGoroutines = 20
)

Only Some Types Can Be Constant

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. However, I have written another article on the elegant ways to get "effectively constant" slices and maps in Go.

By contrast, in JavaScript, anything can be made constant. JavaScript arrays can be declared as constant, but it doesn't stop the programmer from mutating the elements of the array! The only safety JavaScript's const provides is that the variable can't be explicitly reassigned.

Constants Are Untyped By Default

In Go, variables can have their typed inferred:

thisIsAString := "@wagslane"

Constants, on the other hand, get an untyped flag

const unTypedString = "@wagslane"

An untyped string behaves mostly like a string. That is, it's a string type, but doesn't have a Go value of type string. To give it the official Go type of string, it must be declared:

const typedString string = "@wagslane"

Should You Use Constants?

Yes. Constants are safer.

Use constants wherever possible. Why would you want to be able to accidentally mutate a value that you know should never change? Let the compiler save you from yourself, and use constants as much as possible.

You may be familiar with the idea that global variables in programming are a bad idea. Variables should typically belong to the smallest scope possible.

Constants in Go don't apply to the global variable rule, 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.

Frequently Asked Questions

How do you declare a constant in Go?

Constants are declared with the const keyword. They cannot use the := short declaration syntax.

Can Go constants be calculated?

Yes. Constants can be computed as long as the computation can happen at compile time.

Can the value of a Go constant change?

No. The value of a constant cannot be changed after it has been declared.

Which types can be constants in Go?

Strings, integers, booleans, floats, and other numeric types can be constants. Slices, maps, and structs cannot.

How are Go constants different from JavaScript constants?

Go constants deal with compile-time values. JavaScript const prevents a name from being reassigned, but an array or object declared with const can still be mutated.

Related Articles