Skip to main content

Arrays

What Is an Array?

A Go array stores a fixed number of values of the same type in contiguous memory. The length is part of the type, so [3]int and [5]int are distinct types.

Unlike many languages where arrays are reference types, Go arrays are value types. Assigning an array to another variable or passing it to a function copies every element.

package main

import "fmt"

func main() {
// Declaration — immediately zero-initialised
var a [3]int // [0 0 0]
a[0] = 10
a[1] = 20
a[2] = 30
fmt.Println(a) // [10 20 30]

// Array literal
b := [3]int{10, 20, 30}
fmt.Println(b) // [10 20 30]

// Let the compiler count the length with ...
c := [...]string{"Go", "Python", "Rust"}
fmt.Println(len(c)) // 3

// Indexed partial initialisation
d := [5]int{1: 100, 3: 300} // [0 100 0 300 0]
fmt.Println(d)
}

Value-Type Semantics

The value-type nature of arrays is the biggest difference from slices.

package main

import "fmt"

func modifyArray(arr [3]int) {
arr[0] = 999 // modifying the copy — original unchanged
}

func modifyArrayPtr(arr *[3]int) {
arr[0] = 999 // passed by pointer — original modified
}

func main() {
original := [3]int{1, 2, 3}

// Value copy
copied := original
copied[0] = 100
fmt.Println(original) // [1 2 3] — unaffected
fmt.Println(copied) // [100 2 3]

// Pass by value
modifyArray(original)
fmt.Println(original) // [1 2 3] — unchanged

// Pass by pointer
modifyArrayPtr(&original)
fmt.Println(original) // [999 2 3] — changed
}

Array Comparison

Go arrays support == and != directly. Two arrays are equal when they have the same type (including length) and every element is equal.

package main

import "fmt"

func main() {
a := [3]int{1, 2, 3}
b := [3]int{1, 2, 3}
c := [3]int{1, 2, 4}

fmt.Println(a == b) // true
fmt.Println(a == c) // false
fmt.Println(a != c) // true

// Compile error: arrays of different lengths cannot be compared
// d := [4]int{1, 2, 3, 4}
// fmt.Println(a == d)
}

Iterating Over Arrays

Use for with range to iterate.

package main

import "fmt"

func main() {
scores := [5]int{90, 85, 78, 92, 88}

// Index and value
for i, v := range scores {
fmt.Printf("scores[%d] = %d\n", i, v)
}

// Index only
for i := range scores {
fmt.Println(i)
}

// Value only (blank identifier for index)
sum := 0
for _, v := range scores {
sum += v
}
fmt.Printf("Sum: %d, Average: %.1f\n", sum, float64(sum)/float64(len(scores)))
}

Multi-Dimensional Arrays

Arrays can have two or more dimensions — useful for matrices and game boards.

package main

import "fmt"

func main() {
// 2-D array declaration
var matrix [3][3]int
for i := 0; i < 3; i++ {
for j := 0; j < 3; j++ {
matrix[i][j] = i*3 + j + 1
}
}
fmt.Println(matrix) // [[1 2 3] [4 5 6] [7 8 9]]

// 2-D array literal
grid := [3][3]string{
{"X", "O", "X"},
{"O", "X", "O"},
{"X", "O", "X"},
}
for _, row := range grid {
fmt.Println(row)
}

// 3-D array (RGB pixel example)
var rgb [2][2][3]uint8
rgb[0][0] = [3]uint8{255, 0, 0} // red
rgb[0][1] = [3]uint8{0, 255, 0} // green
rgb[1][0] = [3]uint8{0, 0, 255} // blue
rgb[1][1] = [3]uint8{255, 255, 0} // yellow
fmt.Println(rgb)
}

Practical Example — Matrix Multiplication

package main

import "fmt"

func matMul(a, b [3][3]int) [3][3]int {
var result [3][3]int
for i := 0; i < 3; i++ {
for j := 0; j < 3; j++ {
for k := 0; k < 3; k++ {
result[i][j] += a[i][k] * b[k][j]
}
}
}
return result
}

func printMatrix(m [3][3]int) {
for _, row := range m {
fmt.Println(row)
}
}

func main() {
a := [3][3]int{
{1, 2, 3},
{4, 5, 6},
{7, 8, 9},
}
b := [3][3]int{
{9, 8, 7},
{6, 5, 4},
{3, 2, 1},
}

fmt.Println("A × B =")
printMatrix(matMul(a, b))
// [30 24 18]
// [84 69 54]
// [138 114 90]
}

Array vs Slice — When to Use an Array

AspectArraySlice
SizeFixed (compile time)Dynamic (runtime)
TypeIncludes size ([3]int)No size ([]int)
CopyFull copyHeader copy (shared backing array)
Zero valueElement zero valuesnil
Comparison== supportedNot supported (use reflect.DeepEqual)
Primary useFixed-size dataGeneral dynamic collections

Prefer arrays when:

  • The size is fixed by design (e.g. SHA-256 hash: [32]byte)
  • Matrix/vector arithmetic
  • You need to use the array itself as a map key (slices cannot be map keys)
// Using an array as a map key — impossible with slices
cache := map[[2]int]int{}
cache[[2]int{1, 2}] = 100
cache[[2]int{3, 4}] = 200
fmt.Println(cache) // map[[1 2]:100 [3 4]:200]