Theory

Array and slice — a shelf that grows

One record is fine, but where does a whole library go? You need a shelf.

An array is a fixed-size shelf: var shelf [3]Item — exactly 3 slots, forever. The size is part of the type ([3]Item and [4]Item are different types!). Multi-dimensional ones exist too: var board [3][3]string — a 3×3 board (tic-tac-toe). In practice you will rarely use a bare array.

A slice is a shelf that grows: []Item (no number). It is Go's standard list type:

var items []Item                 // empty shelf (zero value: nil, safe to use)

items = append(items, Item{Title: "Dune", Pages: 412})
items = append(items, Item{Title: "Hobbit", Pages: 310})

fmt.Println(len(items))          // 2
fmt.Println(items[0].Title)      // Dune — numbering starts at 0!

Three rules:

  • append returns the new slice — always write items = append(items, x) (a bare append(items, x) throws the result away).
  • len(items) — how many records right now.
  • Indexes run from 0 to len-1; items[5] on a 2-item slice crashes the program (a panic). We will check bounds ourselves.

Tip. A slice's zero value is nil — but len of a nil slice is 0 and append onto it works. Lesson 2's safety rule holds here too: an undeclared shelf is just an empty shelf.