Arrays

An array is a numbered sequence of elements of one type with a fixed length that's part of its type: [5]int and [6]int are different types. In everyday Go you'll use slices (next lesson) far more often, but slices are built on arrays, and arrays are the right tool for small fixed-size data such as coordinates, RGB colours or a chess board.

Declaring arrays

GO
package main

import "fmt"

func main() {
	var scores [5]int // five zeros
	scores[0] = 90
	scores[4] = 75
	fmt.Println(scores, len(scores))

	primes := [6]int{2, 3, 5, 7, 11, 13}
	fmt.Println(primes[2], primes[len(primes)-1])

	weekdays := [...]string{"Mon", "Tue", "Wed", "Thu", "Fri"} // length counted for you
	fmt.Println(len(weekdays), weekdays)

	sparse := [5]string{1: "one", 3: "three"} // set specific indexes
	fmt.Printf("%q\n", sparse)
}
Output
[90 0 0 0 75] 5
5 13
5 [Mon Tue Wed Thu Fri]
["" "one" "" "three" ""]

Elements you don't set get the zero value. With [...] the compiler counts the elements and fixes the length. Indexes start at 0, so the last element is at len(a)-1.

Bounds checking

Go checks every index. A constant index that's out of range is a compile error; an out-of-range index computed at run time causes a panic instead of silently reading other memory:

GO
package main

func main() {
	var a [3]int
	a[5] = 1
}
Compiler error
./main.go:5:4: invalid argument: index 5 out of bounds [0:3]
GO
package main

import "fmt"

func main() {
	a := [3]int{10, 20, 30}
	for i := 0; i <= len(a); i++ { // off by one: <= should be <
		fmt.Println(a[i])
	}
}
Output
10
20
30
panic: runtime error: index out of range [3] with length 3

goroutine 1 [running]:
…
exit status 2

Arrays are values

Assigning an array or passing it to a function copies all of its elements. Changing the copy leaves the original untouched:

GO
package main

import "fmt"

func double(nums [3]int) {
	for i := range nums {
		nums[i] *= 2
	}
	fmt.Println("inside:", nums)
}

func main() {
	a := [3]int{1, 2, 3}
	b := a // a full copy
	b[0] = 100
	fmt.Println(a, b)

	double(a)
	fmt.Println("after:", a)
}
Output
[1 2 3] [100 2 3]
inside: [2 4 6]
after: [1 2 3]

This is different from many languages, where arrays are references. Copying is cheap for small arrays but wasteful for big ones — another reason slices are usually preferred.

Comparing arrays

Arrays of the same type can be compared with ==, which checks every element. That also means they can be used as map keys:

GO
package main

import "fmt"

func main() {
	a := [3]int{1, 2, 3}
	b := [3]int{1, 2, 3}
	fmt.Println(a == b, a != [3]int{3, 2, 1})

	visited := map[[2]int]bool{} // grid positions as keys
	visited[[2]int{0, 0}] = true
	visited[[2]int{2, 5}] = true
	fmt.Println(visited[[2]int{2, 5}], visited[[2]int{1, 1}])
}
Output
true true
true false

Multi-dimensional arrays

An array of arrays makes a grid:

GO
package main

import "fmt"

func main() {
	var board [3][3]rune
	for r := range board {
		for c := range board[r] {
			board[r][c] = '.'
		}
	}
	board[1][1] = 'X'
	board[0][2] = 'O'

	for _, row := range board {
		fmt.Println(string(row[:]))
	}
}
Output
..O
.X.
...

row[:] turns the array into a slice of all its elements, which string() can then convert. You'll learn about slicing in the next lesson.

When to use arrays

  • The size is genuinely fixed and small: [3]float64 for a 3-D point, [4]byte for an IPv4 address, [32]byte for a SHA-256 hash.
  • You want a comparable value to use as a map key.
  • Everything else — lists that grow, data read from input, function parameters — should be a slice.

Try it yourself

Store a week of temperatures in an array and find the warmest day.

Try it yourself · main.go
Edit the code, copy it into main.go in a new folder and run it with go run main.go (Go 1.27 or later). How to install Go
Output
warmest: Thu (24.8°C)
Next: slices — Go's flexible lists.