Arrays

Reviewed & published by Brayan K

Arrays are the fixed-size foundation that slices (your next lesson) are built on. You'll learn to declare them, index them, and — crucially — understand that Go arrays are values: copying or passing one copies every element. That single fact explains a lot of Go behaviour.

Part of the free Go course at LearnCodingFast — hands-on lessons with worked examples and the output they print, plus practice exercises and a quick quiz.

What You'll Learn in This Lesson

1️⃣ Declaring & Indexing

An array's length is part of its type: [5]int and [3]int are different types that can't be mixed. Declared without values, every element starts at the element type's zero value. You index with square brackets, starting at 0, and len() tells you the length (which never changes).

package main

import "fmt"

func main() {
    // An array has a FIXED length that is part of its type.
    // [5]int and [3]int are DIFFERENT types.

    var scores [5]int            // five ints, all zero by default
    fmt.Println(scores)          // [0 0 0 0 0]

    // Set and read elements by index (0-based).
    scores[0] = 90
    scores[4] = 75
    fmt.Println(scores)          // [90 0 0 0 75]
    fmt.Println("first:", scores[0]) // first: 90

    // Array literal — give the values up front.
    primes := [4]int{2, 3, 5, 7}
    fmt.Println(primes)          // [2 3 5 7]

    // len() reports the length (always the same for an array).
    fmt.Println("length:", len(primes)) // length: 4
}

2️⃣ The [...] Form & Iterating

Typing the count by hand is error-prone, so Go lets you write [...] and it counts the literal for you. You can also set elements by index inside a literal (handy for sparse data), and you iterate exactly like any collection — with range.

package main

import "fmt"

func main() {
    // [...] lets Go COUNT the length from the literal for you.
    days := [...]string{"Mon", "Tue", "Wed", "Thu", "Fri"}
    fmt.Println("days:", len(days)) // days: 5

    // You can index specific positions in a literal too.
    // Here index 9 is set; the gaps fill with the zero value.
    grades := [10]int{0: 100, 9: 55}
    fmt.Println(grades) // [100 0 0 0 0 0 0 0 0 55]

    // Sum the array with range.
    nums := [...]int{4, 8, 15, 16, 23, 42}
    sum := 0
    for _, n := range nums {
        sum += n
    }
    fmt.Println("sum:", sum) // sum: 108
}

3️⃣ Arrays Are Values

This is the single most important thing about Go arrays. Assigning an array to another variable, or passing it to a function, copies every element. The original is untouched by changes to the copy. (Slices, next lesson, behave differently — they share underlying storage.) Because they're plain values, two arrays of the same type can be compared with ==.

package main

import "fmt"

func main() {
    // KEY IDEA: arrays are VALUES. Assigning or passing an array
    // COPIES the whole thing — changes to the copy don't affect
    // the original. (This is different from slices, next lesson!)

    a := [3]int{1, 2, 3}
    b := a            // b is a full, independent copy
    b[0] = 99
    fmt.Println("a:", a) // a: [1 2 3]   (unchanged)
    fmt.Println("b:", b) // b: [99 2 3]

    // Passing to a function copies too.
    double(a)
    fmt.Println("after double:", a) // after double: [1 2 3]

    // Arrays of the same type are comparable with ==.
    fmt.Println(a == [3]int{1, 2, 3}) // true
}

func double(arr [3]int) {
    for i := range arr {
        arr[i] *= 2   // mutates the LOCAL copy only
    }
}

Your turn — declare a three-string array and fill the podium.

package main

import "fmt"

func main() {
    // 🎯 YOUR TURN — replace each ___ then run it.

    // 1) Declare an array of 3 strings called "podium"
    var podium ___              // 👉 [3]string

    // 2) Fill the places
    podium[0] = "Gold"
    podium[1] = "Silver"
    podium[___] = "Bronze"      // 👉 2  (the third, 0-based)

    fmt.Println(podium)

    // ✅ Expected output:  [Gold Silver Bronze]
}

Now average a set of temperature readings.

package main

import "fmt"

func main() {
    // 🎯 YOUR TURN — finish the loop then run it.
    temps := [...]int{20, 22, 19, 24}
    total := 0

    for _, t := range ___ {     // 👉 temps
        total += t
    }
    avg := total / len(temps)
    fmt.Println("average:", avg)

    // ✅ Expected output:  average: 21
}

🧩 Reorder Challenge

These lines declare an array and set three slots, but they're scrambled. Put them in order so the program prints [10 50 99] (assume a func main wraps them).

    a[1] = 50
    fmt.Println(a)
    var a [3]int
    a[0] = 10
    a[2] = 99

Why: the array must exist (var a [3]int) before any index can be assigned. The three assignments fill positions 0, 1 and 2 — they can be in any order among themselves, but all must precede the Println. The result is [10 50 99].

Pro Tips

Common Errors (and the fix)

📋 Quick Reference

TaskSyntax
Declare (zeroed)var a [5]int
Literala := [3]int{1, 2, 3}
Auto-counta := [...]int{1, 2, 3}
Indexed literal[5]int{0: 9, 4: 1}
Lengthlen(a)
Comparea == b

🧠 Quick Recall

Predict the output before you reveal the answer.

var a [3]int; fmt.Println(a)

[0 0 0] — a fresh array fills with the element type's zero value, which is 0 for int.

a := [2]int{1, 2}; b := a; b[0] = 9; fmt.Println(a[0])

1 — b := a copies the whole array, so changing b[0] leaves a untouched.

3 — [...] tells Go to count the three literal elements, so the length is 3.

Frequently Asked Questions

Q: Should I use arrays or slices?

Slices, almost always — they're flexible and resizable. Use a true array only when the length is genuinely fixed and known at compile time, or when you need value semantics and comparability.

Q: Why didn't my function change the array?

Arrays are copied when passed, so the function edited a copy. Pass a slice of the array (arr[:]) or a pointer (*[N]T) to mutate the original.

Q: Can I grow an array later?

No — an array's length is fixed forever. If you need to add elements, that's exactly what a slice is for (next lesson).

Mini-Challenge: Find the Maximum

Loop through the readings and track the largest value you've seen. Start max at the first element. Write it yourself and match the example output.

package main

import "fmt"

func main() {
    // 🎯 MINI-CHALLENGE: Find the maximum
    // Given the fixed array below, find and print the largest value
    // WITHOUT using any library — just a loop and a comparison.
    // Start your "max" at the first element, then compare the rest.
    //
    // ✅ Example output:  max = 91

    readings := [...]int{37, 91, 12, 88, 45}
    // your code here
}

🎉 Lesson Complete!

Practice quiz

What is printed by: var scores [5]int; fmt.Println(scores)?

  • [ ]
  • [5]int{}
  • [0 0 0 0 0]
  • a nil error

Answer: [0 0 0 0 0]. A declared array fills every element with the element type's zero value, which is 0 for int.

Given a := [3]int{1,2,3}; b := a; b[0] = 99 — what is a[0]?

  • 1
  • 99
  • 0
  • undefined

Answer: 1. Arrays are values: b := a copies every element, so changing b leaves a untouched. a[0] is still 1.

What does len([...]string{"a","b","c"}) return?

  • 0
  • 2
  • It is a compile error
  • 3

Answer: 3. The [...] form tells Go to count the literal's elements, so the length is 3.

Are [3]int and [5]int the same type?

  • Yes, both are int arrays
  • No — the length is part of the type
  • Only if they hold equal values
  • Only inside a function

Answer: No — the length is part of the type. An array's length is part of its type, so [3]int and [5]int are different, incompatible types.

What is the valid index range for a length-5 array?

  • 0 to 4
  • 1 to 5
  • 0 to 5
  • 1 to 4

Answer: 0 to 4. Indexes are 0-based, so a length-5 array runs from index 0 to 4. Index 5 is out of range.

What does [10]int{0: 100, 9: 55} produce?

  • [100 55]
  • a compile error
  • [100 0 0 0 0 0 0 0 0 55]
  • [55 ... 100]

Answer: [100 0 0 0 0 0 0 0 0 55]. Indexed literals set positions 0 and 9; the gaps fill with the zero value 0.

If you pass an array to a function and it modifies elements, what does the caller see afterward?

  • The changes — arrays are shared
  • No changes — the array was copied
  • A panic
  • Only the first element changes

Answer: No changes — the array was copied. Passing an array copies it, so the function mutates a local copy and the original is unchanged.

Can two arrays of the same type be compared with ==?

  • No, never
  • Only pointers can
  • Only with reflect
  • Yes, if same type and length

Answer: Yes, if same type and length. Arrays of the same type and length are comparable with ==, comparing element by element.

After summing [...]int{4,8,15,16,23,42} with range, what is the total?

  • 100
  • 108
  • 96
  • 120

Answer: 108. 4+8+15+16+23+42 = 108.

Why can a fixed array be used as a map key but a slice cannot?

  • Arrays are smaller
  • Maps require pointers
  • Arrays are comparable; slices are not
  • Slices are immutable

Answer: Arrays are comparable; slices are not. Map keys must be comparable. Arrays are comparable with ==, but slices are not, so slices can't be keys.

Continue this course

Related lessons