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
| Aspect | Array | Slice |
|---|---|---|
| Size | Fixed (compile time) | Dynamic (runtime) |
| Type | Includes size ([3]int) | No size ([]int) |
| Copy | Full copy | Header copy (shared backing array) |
| Zero value | Element zero values | nil |
| Comparison | == supported | Not supported (use reflect.DeepEqual) |
| Primary use | Fixed-size data | General 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]