Working with array in Go.

Array in Go is just a data structure that hold a collection of elements of any type. Each element can be accessed by its index. Length of array is fixed at compile time and its size is a part of its type.

The type [n]T is an array of n values of type T. It can be declared as full declaration statement or in a short-hand format, with or without init values.

Array also can be declared in form of [...]T where its size will be determined by the compiler.

var holidays = [7]bool{}
seasons := [4]string{"Spring", "Summer", "Autumn", "Winter"}
weekDays := [7]int{1, 2, 3, 4, 5, 6, 7}
fruits := [...]string{"apple", "guava", "orange"} // type [3]string
visited := [10]bool{1: true, 3: true, 5: true, 7: true, 9: true}
sudoku := [9][9]int{}

Size of array is a part of its type and it is determined at the compile time

That means you cannot extend its size at run-time and cannot assign it to another type at run-time:

fruits := [...]string{"apple", "guava", "orange"} // type: [3]string
moreFruits := [4]string{"grapes"} // type: [4]string

moreFruits = fruits // compile error

Arrays are comparable if they have same type

firstArr := [3]int{1, 2, 3}    // type: [3]int
secondArr := [3]int{1, 2, 3} // type: [3]int
thirdArr := [4]int{1, 2, 3, 4} // type: [4]int

fmt.Println(firstArr == secondArr) // true

fmt.Println(secondArr == thirdArr) // compile error

Each elements can be accessed by index or range over the array. Access index out of the array will cause a panic

var weekDays [7]string
weekDays[0] = "Sunday"
weekDays[1] = "Monday"
weekDays[2] = "Tuesday"
weekDays[3] = "Wednesday"
weekDays[4] = "Thursday"
weekDays[5] = "Friday"
weekDays[6] = "Saturday"

fmt.Println(weekDays[5])
fmt.Println("Days in a week:")
for _, day := range weekDays {
fmt.Printf("\t%s\n", day)
}

// fmt.Println(weekDays[7]) // panic: index out of bound

Passing an array to a method will create a copy of the original array

This means what you do with the copied array will not affect to the original array.

package main

import "fmt"

func main() {
fruits := [3]string{"apple", "orange"}
addGuava(fruits) // doesn't change values of variable "fruits"
}

func addGuava(fruits [3]string) {
fruits[2] = "guava"
}

Playground

Passing the pointer of the array to a function if you want to change its value in that function:

package main

import "fmt"

func main() {
fruits := [3]string{"apple", "orange"}
addGuava(&fruits) // change value of variable "fruits"
}

func addGuava(fruits *[3]string) {
fruits[2] = "guava"
}

Playground

Assign or range statement on an array will also create a copy of the original array

arr := [4]int{0, 1, 2, 3}
newArr := arr

fmt.Printf("%p != %p", &arr, &newArr) // 0xc000126000 != 0xc000126020

Playground

Interact with value of array while ranging over it will not affect the original value:

arr := [4]int{0, 1, 2, 3}
for _, v := range arr {
v += 100 // will not affect the original array values
}
fmt.Println(arr) // [0, 1, 2, 3]

Playground

If you want to change value of original array while ranging over it, use index instead:

arr := [4]int{0, 1, 2, 3}
for i := 0; i < len(arr); i++ {
arr[i] += 100
}
fmt.Println(arr) // [100 101 102 103]

Playground

Pointer of index and value inside range statement will be reused.

Notice that the pointers of i and v are the same in the result:

arr := [3]int{1, 2, 3}
for i, v := range arr {
fmt.Printf("i=%d, v=%d, &i=%p, &v: %p\n", i, v, &i, &v) // i, v point to the same addresses for each iteration
}

Playground

This will cause a problem if you use goroutine inside the for loop as below. Notice that only the last element is printed.

arr := [3]int{1, 2, 3}
for i, v := range arr {
go func() {
fmt.Printf("i=%d, v=%d, &i=%p, &v: %p\n", i, v, &i, &v)
}()
}

Playground

Define local variable to avoid the variables are captured is one way to avoid the above problem:

arr := [3]int{1, 2, 3}
for i, v := range arr {
i, v := i, v
go func() {
fmt.Printf("i=%d, v=%d, &i=%p, &v: %p\n", i, v, &i, &v)
}()
}

Playground

When do you use array?

Normally, array is used when the number of element is fixed at compile time. Example: