Loops and Iteration

Overview

Go has only one looping construct: the for loop. This single keyword handles all looping patterns.

The Basic for Loop

for i := 0; i < 10; i++ {
    fmt.Println(i)
}

The while Loop (Condition Only)

n := 1
for n < 100 {
    n *= 2
}

The Infinite Loop

for {
    if done {
        break
    }
}

The range Loop

Slices and Arrays

nums := []int{10, 20, 30}

for i, v := range nums {
    fmt.Printf("%d: %d\n", i, v)
}

for _, v := range nums {  // Value only
    fmt.Println(v)
}

Maps

ages := map[string]int{"Alice": 30, "Bob": 25}

for key, value := range ages {
    fmt.Printf("%s: %d\n", key, value)
}

Strings

for i, r := range "Hello" {
    fmt.Printf("%d: %c\n", i, r)
}

Channels

for v := range ch {  // Exits when channel closes
    fmt.Println(v)
}

Iterators (Go 1.23+)

Go 1.23 introduced “range-over-func,” allowing you to use range with custom iterator functions.

Sequence Iterators

A sequence iterator is a function that takes a yield function: func(yield func(V) bool) (single value) or func(yield func(K, V) bool) (key-value).

func All[T any](s []T) iter.Seq[T] {
    return func(yield func(T) bool) {
        for _, v := range s {
            if !yield(v) {
                return
            }
        }
    }
}

// Usage
for v := range All(nums) {
    fmt.Println(v)
}

Pull Iterators

For more control, you can use pull iterators:

next, stop := iter.Pull(All(nums))
defer stop()

for {
    v, ok := next()
    if !ok {
        break
    }
    fmt.Println(v)
}

Loop Control

break and continue

for i := 0; i < 10; i++ {
    if i == 5 {
        break     // Exit loop
    }
    if i%2 == 0 {
        continue  // Skip to next iteration
    }
    fmt.Println(i)
}

Labels for Nested Loops

outer:
for i := 0; i < 3; i++ {
    for j := 0; j < 3; j++ {
        if i == 1 && j == 1 {
            break outer  // Break both loops
        }
    }
}

Common Patterns

// Reverse iteration
for i := len(items) - 1; i >= 0; i-- {
    process(items[i])
}

// Step by N
for i := 0; i < 100; i += 10 {
    fmt.Println(i)
}

Summary

Pattern Syntax
Classic for for i := 0; i < n; i++ {}
While loop for condition {}
Infinite loop for {}
Range for i, v := range slice {}
Iterators for v := range myIter() {}