Skip to content

Beginner · Collections and structs · topic 11 of 46 · 35 min

Arrays and slices

Explanation

An array has a fixed length that is part of its type, like [5]int, and is copied when you assign it. A slice, like []int, is a flexible view of an array that can grow with append. In real Go code you use slices almost all the time.

Why collections?

A program rarely works with one value. A class has 40 students, a cart has 6 items, a day has 24 hourly temperatures. A collection holds many values of the same type under one name, and you reach each value by its index (position), starting at 0.

Arrays: fixed size

go
var marks [5]int              // [0 0 0 0 0]
marks[0] = 78
days := [7]string{"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"}
primes := [...]int{2, 3, 5, 7} // ... lets Go count: [4]int
fmt.Println(len(days), primes[2]) // 7 5
The length is part of the type: [5]int and [4]int are different types.

Arrays are values. Assigning an array or passing it to a function copies every element. Two arrays of the same type can be compared with ==.

go
a := [3]int{1, 2, 3}
b := a       // a full copy
b[0] = 99
fmt.Println(a, b, a == b) // [1 2 3] [99 2 3] false
Changing b does not touch a.

Because their size is fixed, arrays are used for things that truly never change size: the 12 months, an RGB colour [3]uint8, a SHA-256 hash [32]byte.

Slices: the everyday collection

A slice is a window onto an array. It has a length that can change, so it can grow as you add items. Its type has no number: []int, []string.

go
cart := []string{"rice", "dal"}     // a slice literal
cart = append(cart, "ghee")          // add to the end
fmt.Println(cart, len(cart))         // [rice dal ghee] 3
fmt.Println(cart[1])                 // dal
cart[0] = "basmati rice"
for i, item := range cart {
	fmt.Println(i+1, item)
}
append returns the updated slice, so you always assign the result back: cart = append(cart, ...).

make: a slice of a given size

go
scores := make([]int, 3)       // [0 0 0], len 3
names := make([]string, 0, 50) // empty, but room for 50 (capacity)
names = append(names, "Asha")
fmt.Println(scores, names, len(names), cap(names)) // [0 0 0] [Asha] 1 50
make([]T, length, capacity). The capacity is optional; it is explained in the next topic.

Slicing: taking a part

go
nums := []int{10, 20, 30, 40, 50}
fmt.Println(nums[1:3]) // [20 30]   from index 1 up to (not including) 3
fmt.Println(nums[:2])  // [10 20]   from the start
fmt.Println(nums[3:])  // [40 50]   to the end
fmt.Println(nums[:])   // [10 20 30 40 50]
s[low:high] includes low and excludes high, like Python.
Careful: Reading or writing past the end crashes the program with a panic: "index out of range [5] with length 3". Check len(s) before using an index that comes from user input.

Slices of slices

go
seats := [][]string{
	{"A1", "A2", "A3"},
	{"B1", "B2"},
}
fmt.Println(seats[1][0]) // B1
fmt.Println(len(seats))  // 2 rows
A slice whose elements are slices: a simple 2D table where rows can have different lengths.
Array [n]TSlice []T
SizeFixed, part of the typeCan grow with append
Assign / passCopies all elementsCopies only the small header; shares the data
Compare with ==YesNo (only with nil)
Zero valueAll elements zeronil (length 0)
Used forFixed-size data (hashes, RGB)Almost everything else
Tip: If you know roughly how many items you will add, create the slice with make([]T, 0, n). append then does not need to grow and copy the data again and again.

Need help?

Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.

Try:

Watch the lesson

Arrays and slices · 1/7

Arrays and slices

Programs work with many values at once. Go has arrays and slices for lists.

Prefer a video by a teacher? Find free videos on “golang arrays vs slices append make tutorial” on YouTube ↗

In real life: A shopping cart

A grocery delivery app keeps the cart as a slice of item names and a slice of prices. Items are added with append as the user taps, and the total is calculated with a range loop. Arrays would not work here: nobody knows in advance how many items a customer will add.

go
package main

import "fmt"

func main() {
	items := []string{}
	prices := []int{}

	items = append(items, "Atta 5kg")
	prices = append(prices, 265)
	items = append(items, "Toor dal 1kg")
	prices = append(prices, 160)

	total := 0
	for i := range items {
		fmt.Printf("%-14s Rs %d\n", items[i], prices[i])
		total += prices[i]
	}
	fmt.Println("Total: Rs", total) // Total: Rs 425
}
%-14s pads the name to 14 characters, left-aligned, so the prices line up.

Practice (0/4 done)

Task 1 · Question

What does this print? s := []int{5, 6, 7, 8} fmt.Println(s[1:3])

Task 2 · Question

What does this print? a := [2]int{1, 2} b := a b[1] = 5 fmt.Println(a)

Task 3 · Question

Which line does not compile? 1: s := []int{1} 2: append(s, 2) 3: fmt.Println(s)

Task 4 · Practice

Store the marks of 5 students in a slice, add a sixth with append, print the average as a float with 1 decimal, and print the marks of the first three students using slicing.

Quick quiz

Question 1

1.What is the type of [...]int{1, 2, 3}?

Question 2

2.What does make([]int, 3) give?

Question 3

3.Can you compare two slices with ==?

Question 4

4.What happens when you read s[10] and len(s) is 3?

Read more (free)

Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.

What is the type of [...]int{1, 2, 3}?

Answer: [3]int

... asks the compiler to count the elements, so it is an array of length 3.

What does make([]int, 3) give?

Answer: [0 0 0]

make with length 3 creates three zero-valued elements.

Can you compare two slices with ==?

Answer: No, only a slice with nil

Slices are not comparable; use slices.Equal to compare contents.

What happens when you read s[10] and len(s) is 3?

Answer: A run-time panic: index out of range

Out-of-range indexes panic at run time (or fail to compile if the index is a constant and the array size is known).

What does slices.Index(s, x) return when x is not in s?Related

Answer: -1

Like many Go search functions, it returns -1 for "not found".

From Slices in depth: length, capacity and sharing

What does a slice contain?Related

Answer: A pointer and a length

A slice is a fat pointer: where it starts and how many items.

From Slices and strings

After x = [1, 2] and x.append([3, 4]), what is len(x)?Related

Answer: 3

append adds its argument as ONE item, so x becomes [1, 2, [3, 4]], which has 3 items.

From List methods and slicing

What is the index of the last item in an array of length 8?Related

Answer: 7

Indexes go from 0 to Length - 1.

From Arrays: one name, many values

Pass the quiz (60% or more) or mark this topic as done when you are ready.

Your progress is saved on this device only.

Next steps

  1. 4 more topics in “Collections and structs” before its exam: Slices in depth: length, capacity and sharing, Strings, bytes and runes, Maps: key-value look-ups, Structs and methods.
  2. Module 3 exam: Collections and structs · 15 questions · 25 min, without help. 5 topics of this module still to finish first.
  3. Then the next module, Pointers, interfaces and errors. 46 topics left in the course before the final exam.

← Previous: defer: clean up at the end