July 7, 2026

Go Arrays, Slices, and Maps – Working with Collections

Updated July 2, 2026. Refreshed for Go 1.22+ and current SEO best practices.

In this lesson we cover Go arrays, slices, and maps — the three main ways to store collections of data. If you completed Go Functions, you already know how to pass values around. Now you will learn how to group them into ordered lists and key-value lookups. This Go slices tutorial focuses on slices because they are the collection type you will use most often in real programs.

Prerequisites: Lessons 1–6 completed, Go 1.22 or newer installed. Estimated time: 45–60 minutes.

Go Programming Tutorial Series Overview

Follow these twelve lessons in order. Each includes runnable code and clear explanations:

Lesson Topic Link
1 Go Programming Introduction Lesson 1
2 Go Programming Setup Lesson 2
3 Go Basic Syntax Lesson 3
4 Go Variables and Types Lesson 4
5 Go Control Flow Lesson 5
6 Go Functions Lesson 6
7 Go Arrays, Slices, and Maps (this lesson) You are here
8 Go Structs and Methods Lesson 8
9 Go Pointers Lesson 9
10 Go Interfaces and Errors Lesson 10
11 Go Goroutines and Channels Lesson 11
12 Go HTTP REST API Lesson 12

1. Arrays — Fixed-Size Collections

An array in Go is a sequence of elements of the same type with a fixed length determined at compile time. The length is part of the array’s type — [3]int and [5]int are different types and cannot be assigned to each other.

Declare an array by specifying the length and type, then provide values in curly braces:

package main

import "fmt"

func main() {
	// Array of 5 integers, all zero-initialized
	var scores [5]int

	// Array with literal values
	days := [7]string{"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"}

	// Let the compiler count elements with ...
	primes := [...]int{2, 3, 5, 7, 11}

	scores[0] = 95
	fmt.Println(scores[0])       // 95
	fmt.Println(len(days))       // 7
	fmt.Println(len(primes))     // 5
}

Arrays are useful when you know the exact size upfront — for example, the seven days of the week or a fixed-size buffer. In most application code, however, you need collections that can grow and shrink. That is where slices come in.

2. Slices — Dynamic Views Over Arrays

A slice is a flexible, dynamically sized view into an underlying array. Slices are reference types: assigning one slice variable to another copies the slice header (pointer, length, capacity) but not the elements themselves. This is why slices appear everywhere in Go — from parsing HTTP requests to processing JSON.

You can create a slice in several ways:

  • Slice literal: nums := []int{1, 2, 3}
  • From an array: arr := [5]int{10, 20, 30, 40, 50}; s := arr[1:4] — elements at indices 1, 2, 3
  • With make: make([]int, length, capacity)
package main

import "fmt"

func main() {
	// Slice literal
	fruits := []string{"apple", "banana", "cherry"}

	// make(type, length, capacity)
	// length = number of accessible elements
	// capacity = total space in the backing array
	buffer := make([]byte, 0, 16)

	fmt.Println(fruits)          // [apple banana cherry]
	fmt.Println(len(buffer))     // 0
	fmt.Println(cap(buffer))     // 16
}

3. append, len, and cap

Three functions and built-ins define everyday slice work:

  • len(s) — returns the number of elements currently in the slice
  • cap(s) — returns the capacity of the underlying array from the slice’s start index
  • append(s, elements...) — adds elements to the end, growing the slice when needed

When append exceeds capacity, Go allocates a new, larger backing array (typically doubling capacity), copies existing elements, and returns the updated slice. Always assign the result back to your variable:

package main

import "fmt"

func main() {
	nums := []int{1, 2, 3}
	fmt.Printf("len=%d cap=%d %v\n", len(nums), cap(nums), nums)

	nums = append(nums, 4, 5, 6)
	fmt.Printf("len=%d cap=%d %v\n", len(nums), cap(nums), nums)

	// append can add another slice with ...
	more := []int{7, 8}
	nums = append(nums, more...)
	fmt.Printf("len=%d cap=%d %v\n", len(nums), cap(nums), nums)
}

Understanding len vs cap helps you write efficient code. Pre-allocating with make([]T, 0, expectedSize) avoids repeated reallocations when you know roughly how many elements you will store — a common pattern in API handlers and data pipelines.

4. Slicing, Copying, and Common Patterns

You can create sub-slices with the syntax s[low:high]. Omitting low defaults to 0; omitting high defaults to len(s):

s := []int{10, 20, 30, 40, 50}
first := s[:2]    // [10 20]
middle := s[1:4]  // [20 30 40]
last := s[3:]     // [40 50]

To copy elements without sharing the backing array, use the built-in copy function:

src := []int{1, 2, 3}
dst := make([]int, len(src))
copy(dst, src)

A nil slice has len 0 and cap 0. You can call append on a nil slice — it works fine. An empty slice literal []int{} is also valid and sometimes preferred when serializing to JSON, because null vs [] matters for API consumers.

5. Maps — Key-Value Collections

A map associates keys with values. Both keys and values have types — for example, map[string]int maps string keys to integer values. Maps are reference types, like slices.

Create a map with make or a literal:

package main

import "fmt"

func main() {
	// Map literal
	ages := map[string]int{
		"Alice": 30,
		"Bob":   25,
	}

	// make(map[KeyType]ValueType)
	scores := make(map[string]int)

	scores["math"] = 92
	scores["science"] = 88

	fmt.Println(ages["Alice"])  // 30
	fmt.Println(scores)         // map[math:92 science:88]
}

Reading a missing key returns the zero value for the value type (0 for int, "" for string). To distinguish “key not found” from “key exists with zero value”, use the two-value form:

score, ok := scores["history"]
if !ok {
	fmt.Println("history score not found")
} else {
	fmt.Println("history:", score)
}

Delete a key with delete(scores, "math"). Maps are not safe for concurrent access from multiple goroutines without synchronization — you will learn about that in the goroutines lesson.

6. Iteration with range

The range keyword iterates over slices, arrays, maps, strings, and channels. For slices and arrays, range provides the index and value:

package main

import "fmt"

func main() {
	colors := []string{"red", "green", "blue"}

	// Index and value
	for i, color := range colors {
		fmt.Printf("%d: %s\n", i, color)
	}

	// Value only — use _ to ignore the index
	for _, color := range colors {
		fmt.Println(color)
	}

	// Map iteration — key and value
	capital := map[string]string{
		"Nigeria": "Abuja",
		"Kenya":   "Nairobi",
		"Ghana":   "Accra",
	}

	for country, city := range capital {
		fmt.Printf("%s → %s\n", country, city)
	}
}

Map iteration order is randomized in Go — do not depend on any particular order. If you need sorted output, collect keys into a slice and sort them first (using the sort package).

7. Arrays vs Slices vs Maps — Quick Reference

Type Size Access Typical Use
Array Fixed at compile time Index [i] Fixed buffers, low-level code
Slice Dynamic (append) Index [i] Lists, sequences, most collections
Map Dynamic (grows automatically) Key [key] Lookups, counting, grouping

8. Next Steps

You now understand Go arrays, slices, and maps — how to create them with literals and make, grow slices with append, inspect size with len and cap, and iterate with range. In the next lesson we cover structs and methods — Go’s way to group related data and attach behavior to types.

Continue the series: Lesson 6 – Functions · Lesson 8 – Structs and Methods

Frequently Asked Questions

What is the difference between arrays and slices in Go?
Arrays have a fixed size that is part of their type. Slices are dynamic views backed by an array and are used far more often in real Go programs.

How do you append to a slice in Go?
Use append(slice, element) and assign the result back: slice = append(slice, value). When capacity is exceeded, Go allocates a new backing array automatically.

Are Go maps ordered?
No. Map iteration order is randomized. Sort keys separately if you need a consistent order in output.

Want live Go or backend classes? Join Alkademy for instructor-led programming courses with hands-on projects.


0 0 votes
Article Rating
Subscribe
Notify of
0 Comments
Oldest
Newest Most Voted
0
Would love your thoughts, please comment.x
()
x