Arrays and Slices

Course 1 · Ch 6
Arrays and Slices
Go actually has two list-like types — but only one of them gets used in everyday code

Chapter 4 already used []string{...} without fully explaining it. Go has both arrays (fixed-size, rarely used directly) and slices (flexible, growable — the real workhorse, and the closest equivalent to a JavaScript array). This chapter covers both, but spends most of its time on slices, since that's what real Go code uses almost everywhere.

Arrays — Fixed Size, Part of the Type Itself

var scores [3]int = [3]int{88, 72, 95} fmt.Println(scores) // [88 72 95] fmt.Println(scores[0]) // 88 fmt.Println(len(scores)) // 3

[3]int means "an array of exactly 3 ints" — the size is part of the type itself, fixed forever once declared. [3]int and [4]int are considered entirely different types; an array can never grow or shrink. This rigidity is exactly why slices exist and are used almost everywhere instead.

Slices — The Type You'll Actually Use

fruits := []string{"apple", "banana", "cherry"} fmt.Println(fruits[0]) // "apple" fmt.Println(len(fruits)) // 3

[]string — square brackets with no number inside — declares a slice, not an array. That missing number is the entire visual difference between the two, and it matters enormously: a slice can grow after creation, which an array never can.

Growing a Slice with append

numbers := []int{1, 2, 3} numbers = append(numbers, 4) fmt.Println(numbers) // [1 2 3 4] numbers = append(numbers, 5, 6) fmt.Println(numbers) // [1 2 3 4 5 6]

append is the direct equivalent of JavaScript's push (Fundamentals Chapter 6) — with one crucial difference: append returns a new slice rather than modifying in place, so the result must always be reassigned (numbers = append(numbers, 4)). Forgetting the reassignment is a common mistake — the original variable simply won't reflect the new element.

A slice is a "view" onto an underlying array
Behind the scenes, a slice tracks a pointer, a length, and a capacity into a real array Go manages automatically. This is normally invisible day-to-day, but it explains why append sometimes allocates a brand-new underlying array (when capacity runs out) and sometimes doesn't — either way, always use the value append returns.

Slicing a Slice — The [start:end] Syntax

letters := []string{"a", "b", "c", "d", "e"} fmt.Println(letters[1:3]) // [b c] — index 1 up to (not including) index 3 fmt.Println(letters[:2]) // [a b] — from the start, up to index 2 fmt.Println(letters[3:]) // [d e] — from index 3 to the end

letters[1:3] extracts a sub-slice, similar in spirit to JavaScript's array .slice() method, but built directly into Go's bracket syntax rather than a method call. The end index is always exclusive, the same convention as JavaScript's slice().

Iterating and Combining with Earlier Chapters

prices := []float64{9.99, 14.50, 3.25} total := 0.0 for _, price := range prices { total += price } fmt.Printf("Total: %.2f\n", total) // Total: 27.74

Combining Chapter 4's range with a running total is Go's version of JavaScript's reduce — there's no built-in reduce method on slices in Go, so this manual loop pattern is the idiomatic replacement. %.2f in Printf formats a float to exactly 2 decimal places.

JavaScriptGo
const arr = [1, 2, 3];arr := []int{1, 2, 3} (slice)
arr.push(4)arr = append(arr, 4)
arr.lengthlen(arr)
arr.slice(1, 3)arr[1:3]
arr.reduce((sum, x) => sum + x, 0)manual for...range loop with a running total

Coding Challenges

Challenge 1

Create a slice named temps containing the floats 18.5, 22.0, 15.5, then use append to add 30.0 and 27.5 (in one call). Print the final slice and its length using len().

📄 View solution
Challenge 2

Create a slice named words containing 6 short strings of your choice. Print the first 3 using slicing syntax, then print the last 3 using slicing syntax, without using any literal index numbers higher than what's needed for each.

📄 View solution
Challenge 3

Create a slice of ints called scores with at least 5 values. Write a loop that calculates both the total and the average (total / number of scores, as a proper float64 result), printing both using Printf with %.2f.

📄 View solution

Chapter 6 Quick Reference

  • [N]Type — a fixed-size array; size is part of the type, never grows
  • []Type — a slice; flexible, growable, the type used almost everywhere in real Go code
  • append(slice, value) — adds an element; ALWAYS reassign the result back
  • len(slice) — number of elements, works on arrays, slices, strings, and maps
  • slice[start:end] — sub-slice; end index is exclusive, either side can be omitted
  • No built-in map/filter/reduce — manual for...range loops are the idiomatic replacement
  • %.2f — Printf verb for a float formatted to 2 decimal places
  • Next chapter: maps — Go's key/value type, the rough equivalent of a JavaScript object