Rez Moss

Rez Moss

Personal Musings: A Blog for the Tech-Savvy and Curious Mind

New Iterator Features in Go 1.23

Jan 2025

Go 1.23 introduces new iterator features that simplify common programming patterns. Here’s what’s changed and how to use them.

Slice Operations

Backward Iteration

The old way required manual index management:

for i := len(slice) - 1; i >= 0; i-- {
    value := slice[i]
    // use value
}

The new way using slices.Backward:

for i, v := slices.Backward(slice) {
    // use i and v
}

Chunk Processing

Before, processing slices in chunks required manual bounds checking:

for i := 0; i < len(slice); i += chunkSize {
    end := i + chunkSize
    if end > len(slice) {
        end = len(slice)
    }
    chunk := slice[i:end]
    // process chunk
}

Now with slices.Chunk:

for chunk := slices.Chunk(slice, 3) {
    // process chunk
}

Map Operations

Value Iteration

Instead of using blank identifiers:

for _, v := range myMap {
    // use v
}

You can use maps.Values:

for v := maps.Values(myMap) {
    // use v
}

Key Iteration

Similarly for keys:

for k := maps.Keys(myMap) {
    // use k
}

Collection Operations

The new packages add functions for collecting iterator values:

// Create new slice from iterator
result := slices.Collect(iter)

// Append iterator values to existing slice
slices.AppendSeq(existing, iter)

// Create new map from key-value iterator
newMap := maps.Collect(pairsIter)

Sorting

Sorting iterator values is now built-in:

// Basic sorting
sorted := slices.Sorted(iter)

// Custom comparison
sorted := slices.SortedFunc(iter, func(a, b int) bool {
    return a < b
})

When to Use

  • Use standard range for basic iteration
  • Use these functions when you need reversed order, chunking, or iterator operations
  • Consider them for custom data structures that need iteration support

The new features reduce boilerplate and handle edge cases, while keeping the code straightforward and explicit.