Question

How to Declare a Constant Array or Slice in Go

goarraysconstants

Question

I can declare a constant string like this:

const ascii = "abcdefghijklmnopqrstuvwxyz"

But these attempts to declare a constant collection of floating-point values do not work:

const letter_goodness []float32 = { .0817, .0149, .0278, .0425, .1270, .0223, .0202, .0609, .0697, .0015, .0077, .0402, .0241, .0675, .0751, .0193, .0009, .0599, .0633, .0906, .0276, .0098, .0236, .0015, .0197, .0007 }

const letter_goodness = { .0817, .0149, .0278, .0425, .1270, .0223, .0202, .0609, .0697, .0015, .0077, .0402, .0241, .0675, .0751, .0193, .0009, .0599, .0633, .0906, .0276, .0098, .0236, .0015, .0197, .0007 }

const letter_goodness = []float32{ .0817, .0149, .0278, .0425, .1270, .0223, .0202, .0609, .0697, .0015, .0077, .0402, .0241, .0675, .0751, .0193, .0009, .0599, .0633, .0906, .0276, .0098, .0236, .0015, .0197, .0007 }

The string constant works, but the array or slice versions do not. How do you correctly declare and initialize a constant array of floats in Go?

Short Answer

By the end of this page, you will understand why Go allows const for simple compile-time values like strings and numbers, but not for arrays or slices. You will also learn the correct way to store fixed float data in Go using variables, arrays, slices, and patterns that make the data effectively read-only.

Concept

In Go, const is only for constant values known at compile time. That includes values such as:

  • numbers
  • booleans
  • strings
  • rune constants

It does not include:

  • arrays
  • slices
  • maps
  • structs

That is why this works:

const ascii = "abcdefghijklmnopqrstuvwxyz"

A string can be a constant in Go.

But this does not work:

const letterGoodness = []float32{0.0817, 0.0149}

A slice is not a constant type. It is a runtime data structure containing a pointer, length, and capacity.

Similarly, arrays are also not allowed as constants in Go. Even though an array has fixed size, Go still does not permit arrays in const declarations.

So if you want fixed float data, the usual solution is to use a package-level variable:

var letterGoodness = []float32{0.0817, 0.0149, 0.0278}

or a package-level array:

var letterGoodness = [...]float32{0.0817, 0.0149, 0.0278}

This matters in real programs because many values feel “constant” from a design point of view, but Go only treats a narrow set of values as true language constants. For collections, you usually model immutability by convention: initialize once, then do not modify them.

Mental Model

Think of Go const values as values printed directly into the program at compile time.

  • A number constant is like writing a number on paper.
  • A string constant is like printing a fixed label.
  • A slice is more like a small container object that points to data somewhere else.

Go allows const for simple printed values, but not for containers.

So:

  • const "hello" works because it is a simple fixed value.
  • const []float32{...} does not work because a slice is a runtime structure.

If you need a fixed collection, use a variable and treat it as read-only.

Take Quiz

Syntax and Examples

The correct syntax depends on whether you want an array or a slice.

1. Package-level array

Use an array if the size is fixed and known.

var letterGoodness = [...]float32{
	0.0817, 0.0149, 0.0278, 0.0425, 0.1270, 0.0223, 0.0202,
	0.0609, 0.0697, 0.0015, 0.0077, 0.0402, 0.0241, 0.0675,
	0.0751, 0.0193, 0.0009, 0.0599, 0.0633, 0.0906, 0.0276,
	0.0098, 0.0236, 0.0015, 0.0197, 0.0007,
}

[...]float32 tells Go to count the number of elements automatically.

2. Package-level slice

Use a slice if you want slice behavior.

var letterGoodness = []float32{
	0.0817, 0.0149, 0.0278, 0.0425, 0.1270, 0.0223, 0.0202,
	0.0609, 0.0697, 0.0015, 0.0077, 0.0402, 0.0241, 0.0675,
	0.0751, 0.0193, 0.0009, 0.0599, 0.0633, 0.0906, 0.0276,
	0.0098, 0.0236, 0.0015, 0.0197, 0.0007,
}

3. Return a copy to avoid accidental mutation

If you do not want callers to modify shared data, return a copy.

var letterGoodnessData = [...]float32{
	0.0817, 0.0149, 0.0278,
}

func LetterGoodness() []float32 {
	copyData := make([]float32, len(letterGoodnessData))
	copy(copyData, letterGoodnessData[:])
	return copyData
}

This is a common way to make collection data effectively read-only.

Beginner example

package main

import "fmt"

var scores = [...]float32{1.2, 3.4, 5.6}

func main() {
	fmt.Println(scores)
}

This prints the array. It is not a const, but it stores fixed data successfully.

Step by Step Execution

Consider this example:

package main

import "fmt"

var weights = [...]float32{0.5, 1.5, 2.5}

func main() {
	fmt.Println(weights)
	fmt.Println(weights[1])
}

Here is what happens step by step:

  1. Go sees var weights = [...]float32{0.5, 1.5, 2.5}.
  2. var means this is a variable, not a constant.
  3. [...]float32 means:
    • create an array
    • element type is float32
    • count the length from the values provided
  4. Go creates an array of length 3.
  5. The values are stored in order:
    • index 0 → 0.5
    • index 1 → 1.5
    • index 2 → 2.5
  6. In main, fmt.Println(weights) prints the full array.
  7. fmt.Println(weights[1]) prints the element at index 1, which is 1.5.

If you tried the same thing with const, compilation would fail before the program ran, because arrays and slices are not valid constant types in Go.

Real World Use Cases

Even though Go does not support constant arrays or slices, fixed collections are common in real programs.

Common uses

  • Lookup tables: letter frequencies, scoring tables, conversion factors
  • Configuration defaults: default ports, retry delays, allowed file extensions
  • Static reference data: month names, country codes, status labels
  • Parsing and validation: known token lists, keyword lists, accepted values
  • Data science or analysis scripts: weight values, coefficients, sample distributions

Example: letter frequency data

var englishLetterFrequency = [...]float32{
	0.0817, 0.0149, 0.0278, 0.0425, 0.1270, 0.0223, 0.0202,
	0.0609, 0.0697, 0.0015, 0.0077, 0.0402, 0.0241, 0.0675,
	0.0751, 0.0193, 0.0009, 0.0599, 0.0633, 0.0906, 0.0276,
	0.0098, 0.0236, 0.0015, 0.0197, 0.0007,
}

This is ideal for algorithms that score text, detect language, or analyze letter usage.

Take Quiz

Real Codebase Usage

In real Go codebases, developers usually handle “constant-like collections” with one of these patterns.

1. Package-level unexported variable

var defaultTimeouts = []int{1, 2, 5}

This works when only the package uses the data.

2. Unexported data with exported accessor

var defaultTimeouts = [...]int{1, 2, 5}

func DefaultTimeouts() []int {
	out := make([]int, len(defaultTimeouts))
	copy(out, defaultTimeouts[:])
	return out
}

This prevents callers from modifying the original shared data.

3. Guarding against mutation

If shared data must not change, avoid returning the original slice directly.

Broken pattern:

var defaults = []int{1, 2, 3}

func GetDefaults() []int {
	return defaults
}

Any caller can change defaults.

Safer pattern:

func GetDefaults() []int {
	out := make([]int, len(defaults))
	copy(out, defaults)
	return out
}

4. Arrays for fixed-size data

Arrays are useful when the number of items should never change.

var rgb = [3]uint8{255, 128, 0}

This communicates fixed size more clearly than a slice.

5. Constants for individual values

Developers often keep simple values as constants and collections as variables.

const alphabet = "abcdefghijklmnopqrstuvwxyz"
var frequencies = [...]float32{0.0817, 0.0149}

Common Mistakes

1. Trying to use const with a slice

Broken code:

const values = []float32{1.1, 2.2}

Why it fails:

  • slices are not valid constant types in Go

Use this instead:

var values = []float32{1.1, 2.2}

2. Trying to use const with an array

Broken code:

const values = [2]float32{1.1, 2.2}

Why it fails:

  • arrays also cannot be declared as constants in Go

Use this instead:

var values = [2]float32{1.1, 2.2}

3. Forgetting the type in a composite literal

Broken code:

var values = {1.1, 2.2}

Why it fails:

  • Go needs the array or slice type before the values

Correct version:

var values = []float32{1.1, 2.2}

4. Assuming var means unsafe to share

A package-level var is fine for fixed reference data, but remember it can be modified.

Avoid accidental changes by:

  • keeping it unexported
  • returning copies
  • documenting it as read-only

5. Mixing arrays and slices

These are different types:

var a = [3]float32{1, 2, 3}
var s = []float32{1, 2, 3}
  • array: fixed size, part of the type
  • slice: flexible view over an underlying array

Comparisons

ConceptExampleCan use const?Size fixed?Can be resized?
String constantconst s = "abc"YesN/ANo
Number constantconst n = 10YesN/ANo
Arrayvar a = [3]float32{1,2,3}NoYesNo
Slicevar s = []float32{1,2,3}NoNoYes

Array vs slice in Go

FeatureArraySlice
Length is part of typeYesNo
Fixed sizeYesNo
Can use appendNoYes
Good for known-size dataYesSometimes
Can be constNoNo

const vs var

KeywordUse forExample
constcompile-time simple valuesconst pi = 3.14
varruntime variables and all collectionsvar nums = []int{1, 2, 3}

If your data is a collection, use var, not const.

Take Quiz

Cheat Sheet

Quick rules

  • Go const works for:
    • numbers
    • strings
    • booleans
    • runes
  • Go const does not work for:
    • arrays
    • slices
    • maps
    • structs

Valid examples

const name = "go"
const max = 10
const enabled = true

Invalid examples

const nums = []int{1, 2, 3}
const nums = [3]int{1, 2, 3}

Use these instead

Fixed-size array

var nums = [...]float32{1.1, 2.2, 3.3}

Slice

var nums = []float32{1.1, 2.2, 3.3}

Safer read-only style

var data = [...]float32{1.1, 2.2, 3.3}

func Data() []float32 {
	out := make([]float32, len(data))
	copy(out, data[:])
	return out
}

Important edge case

A value can be logically constant in your design, but still not be a Go const.

That is normal for collections in Go.

FAQ

Why can't I declare a constant slice in Go?

Because slices are runtime data structures, not compile-time constant values.

Can I declare a constant array in Go?

No. Go does not allow arrays as const values either.

What should I use instead of a constant array?

Use a package-level var with an array or slice literal.

How do I make slice data read-only in Go?

Go has no built-in read-only slice type. A common pattern is to keep the original data private and return a copy.

Should I use an array or a slice for fixed data?

Use an array when the size is truly fixed and meaningful. Use a slice when you want more flexible APIs.

Is a string different from a slice in Go constants?

Yes. A string can be a constant, but a slice cannot.

Can callers modify a slice returned from a function?

Yes, unless you return a copy. Returning the original slice exposes shared mutable data.

Take Quiz

Mini Project

Description

Build a small Go utility that stores English letter frequency data and looks up the score for a given lowercase letter. This demonstrates how to keep fixed reference data in Go using an array instead of an invalid const collection.

Goal

Create a program that maps letters a to z to their frequency values and prints the value for selected letters.

Requirements

  • Store the alphabet as a string constant.
  • Store the frequency values in a package-level array or slice.
  • Write a function that accepts a lowercase letter and returns its frequency.
  • Return 0 for characters outside a to z.
Take Quiz

Keep learning

Related questions

View more