Declaring an array
An array type is written [N]T: a length, then an element type. The length is fixed at compile time and is part of the type.
Output:
[90 0 0 0 75] 5
Tue
[5]int [2 3 5 7 11]
["" "b" "" "d" ""]
An array is always fully initialized. Elements you do not set hold the zero value of the element type: 0, "", false, nil.
Indexing and bounds
Indexes run from 0 to len(a)-1. A constant index out of range is a compile error. A variable index out of range panics at run time.
var a [3]int
a[5] = 1 // compile error: invalid argument: index 5 out of bounds [0:3]
i := 5
a[i] = 1 // panic: runtime error: index out of range [5] with length 3
Iterating
for i, v := range a visits each element in order. v is a copy of the element, so assigning to v does not change the array. Write through the index instead.
There is one more subtlety specific to arrays: range over an array value evaluates a copy of the array up front. If the body modifies later elements, v still shows the old values. Ranging over &a or a[:] avoids the copy.
Arrays are values
This is the main difference from arrays in C, Java or JavaScript. Assigning an array copies every element. Passing an array to a function copies it too.
Output:
[1 2 3] [99 2 3]
[1 2 3]
[0 2 3]
Copying is cheap for small arrays and expensive for big ones: passing a [1_000_000]int by value copies eight megabytes. Pass a pointer (*[N]T) or a slice (a[:]) when the array is large or the function needs to change it. Indexing through an array pointer needs no explicit *: a[0] works on a *[3]int.
Comparing arrays and using them as map keys
Arrays of comparable elements support == and !=. Two arrays are equal when every element is equal. That also makes them valid map keys, which slices are not.
Arrays of different lengths are different types and cannot be compared at all: [3]int{} == [4]int{} does not compile (mismatched types [3]int and [4]int).
Multidimensional arrays
An array of arrays gives you a fixed grid. The whole grid is one contiguous block of memory.
row[:] turns the [3]rune row into a []rune slice, which string() accepts.
Arrays vs slices
Array [N]T | Slice []T | |
|---|---|---|
| Length | fixed, part of the type | changes with append |
| Assignment and passing | copies all elements | copies a small header, shares elements |
| Zero value | N zero elements | nil, length 0 |
== | yes, element by element | only against nil |
| Map key | yes | no |
| Typical use | fixed-size data: hashes, coordinates, buffers | almost everything else |
In practice you will mostly meet arrays in a few places: sha256.Sum256 returns a [32]byte, lookup tables whose size never changes, and as the backing store of a slice. Slicing an array with a[:] or a[1:3] creates a slice that shares its memory; the slices page covers what that sharing means.
Converting between arrays and slices
Converting a slice to an array (Go 1.20) or an array pointer (Go 1.17) panics if the slice is shorter than the array length: panic: runtime error: cannot convert slice with length 2 to array or pointer to array with length 3.
Common mistakes
- Expecting a function to modify an array argument. It gets a copy. Pass
*[N]Tor a slice. - Using an array where a slice is wanted.
[]int{1, 2}is a slice,[2]int{1, 2}is an array. A function taking[]intwill not accept a[2]int; passa[:]. - Large arrays in a range loop.
for _, v := range bigArraycopies the whole array first. Range over&bigArrayor a slice.
Frequently Asked Questions
How do you declare an array in Go?
Write the length in brackets before the element type: var a [5]int makes five zeros. With values: a := [3]string{"x", "y", "z"}. Use [...] to let the compiler count: a := [...]int{1, 2, 3} has type [3]int.
What is the difference between an array and a slice in Go?
An array has a fixed length that is part of its type ([3]int and [4]int are different types) and is copied when assigned or passed. A slice ([]int) is a view onto an underlying array with a length that can change through append, and copying a slice copies only the view, not the elements. Most Go code uses slices.
How do I get the length of an array in Go?
Use the built-in len(a). For an array it is a compile-time constant, so you can use it in constant expressions. cap(a) returns the same number.
Can you compare arrays in Go?
Yes, with == and !=, if the element type is comparable. Two arrays are equal when all their elements are equal. Arrays can also be map keys. Slices cannot be compared with == (except to nil); use slices.Equal for them.