>_ Golang Step By Step
Software Engineer

Arrays, Slices & Maps

Master Go's core collection types and their internals

# Arrays — Fixed-Size

Arrays have a fixed length that's part of the type.[3]int and [5]int are different types.

var a [3]int                // [0 0 0]
b := [3]int{10, 20, 30}      // explicit
c := [...]int{1, 2, 3, 4}  // compiler counts: [4]int

fmt.Println(a[0])    // 0
fmt.Println(len(b))  // 3
fmt.Println(c)       // [1 2 3 4]

# Slices — Dynamic & Powerful

Slices are the workhorse of Go. They're a lightweight view over an underlying array, with three components: pointer, length, and capacity.

// Creating slices
s1 := []int{1, 2, 3}           // literal
s2 := make([]int, 5)           // len=5, cap=5
s3 := make([]int, 3, 10)       // len=3, cap=10

// Append grows the slice
s1 = append(s1, 4, 5)
fmt.Println(s1)                 // [1 2 3 4 5]

// Slicing (half-open: includes low, excludes high)
sub := s1[1:3]
fmt.Println(sub)                // [2 3]
fmt.Println(len(sub), cap(sub))  // 2 4
▸ More Details: Slice as a Window Analogy
Think of a slice as a window on a wall of post-it notes. The wall is the backing array. The window (slice) shows only some notes. You can slide the window or make it wider (re-slice), but the notes on the wall stay. If you need more wall space, someone builds a bigger wall and moves all the notes (that's what append does when capacity is exceeded).

# Maps — Key-Value Store

Maps are Go's built-in hash table. Keys must be comparable types (no slices, maps, or functions as keys).

// Create and use a map
ages := map[string]int{
    "Alice": 30,
    "Bob":   25,
}

ages["Carol"] = 28             // add
delete(ages, "Bob")             // remove

// Check if key exists
age, ok := ages["Dave"]
if !ok {
    fmt.Println("Dave not found")
}

// Iterate (order is random!)
for name, age := range ages {
    fmt.Printf("%s is %d\n", name, age)
}

# Common Patterns

Filtering a Slice (in-place)

func filterEvens(nums []int) []int {
    result := nums[:0] // reuse backing array
    for _, n := range nums {
        if n%2 == 0 {
            result = append(result, n)
        }
    }
    return result
}

Counting with Maps

words := []string{"go", "is", "go", "fun", "go"}
freq := make(map[string]int)
for _, w := range words {
    freq[w]++
}
fmt.Println(freq) // map[fun:1 go:3 is:1]

⚡ Key Takeaways

  • Arrays are fixed-size value types; slices are dynamic reference types
  • Slices have length and capacity — know the difference
  • Always re-assign the result of append(): s = append(s, x)
  • Use val, ok := m[key] to check map key existence
  • Never write to a nil map — always initialize with make()
practice & review