Go 1.23 Released - Iterators and Telemetry

2025.12.12

Go 1.23 Overview

Go 1.23, released in August 2024, introduces the long-awaited iterator feature (range over func) and includes many improvements to the standard library.

Reference: Go 1.23 Release Notes

Range over Func (Iterators)

Basic Usage

Functions can now be iterated directly in for loops.

package main

import "fmt"

// Define iterator function
func Backward[E any](s []E) func(yield func(E) bool) {
    return func(yield func(E) bool) {
        for i := len(s) - 1; i >= 0; i-- {
            if !yield(s[i]) {
                return
            }
        }
    }
}

func main() {
    s := []string{"a", "b", "c"}

    // Use iterator
    for v := range Backward(s) {
        fmt.Println(v) // c, b, a
    }
}

iter Package

A new standard package iter has been added.

import "iter"

// Seq: Sequence of values
type Seq[V any] func(yield func(V) bool)

// Seq2: Sequence of key-value pairs
type Seq2[K, V any] func(yield func(K, V) bool)

// Pull: Convert push-style to pull-style
func Pull[V any](seq Seq[V]) (next func() (V, bool), stop func())

slices Package Extension

import "slices"

s := []int{1, 2, 3, 4, 5}

// All: Iterate over all elements
for i, v := range slices.All(s) {
    fmt.Printf("index: %d, value: %d\n", i, v)
}

// Backward: Iterate in reverse order
for i, v := range slices.Backward(s) {
    fmt.Println(i, v)
}

// Values: Values only, no index
for v := range slices.Values(s) {
    fmt.Println(v)
}

// Chunk: Split into groups of n
for chunk := range slices.Chunk(s, 2) {
    fmt.Println(chunk) // [1 2], [3 4], [5]
}

Reference: Go iter package

maps Package Extension

import "maps"

m := map[string]int{"a": 1, "b": 2, "c": 3}

// Keys: Iterator over keys
for k := range maps.Keys(m) {
    fmt.Println(k)
}

// Values: Iterator over values
for v := range maps.Values(m) {
    fmt.Println(v)
}

// All: Iterator over keys and values
for k, v := range maps.All(m) {
    fmt.Printf("%s: %d\n", k, v)
}

// Insert: Insert from iterator into map
maps.Insert(m, slices.All([]struct{k string; v int}{{"d", 4}}))

unique Package

Provides memory-efficient value canonicalization (interning).

import "unique"

// String canonicalization
h1 := unique.Make("hello")
h2 := unique.Make("hello")

// Same string returns same handle
fmt.Println(h1 == h2) // true

// Get value
fmt.Println(h1.Value()) // "hello"

// Works with any comparable type
type Point struct{ X, Y int }
p1 := unique.Make(Point{1, 2})
p2 := unique.Make(Point{1, 2})
fmt.Println(p1 == p2) // true

Reference: Go unique package

time.Timer Improvements

Garbage collection and channel behavior have been improved.

import "time"

// Unused Timers are automatically GC'd
timer := time.NewTimer(time.Hour)
// No need to call timer.Stop() for GC

// Reset behavior improved
timer = time.NewTimer(time.Second)
if !timer.Stop() {
    // Go 1.23: Channel is automatically drained
    // Before: <-timer.C was needed
}
timer.Reset(time.Minute)

structs Package (Experimental)

Allows control over struct layout.

import "structs"

type Data struct {
    _     structs.HostLayout  // Use host layout
    Value int64
}

Telemetry

A feature to collect Go toolchain usage has been added.

# Check telemetry status
go telemetry

# Enable telemetry (opt-in)
go telemetry on

# Disable telemetry
go telemetry off

# Local only (no upload)
go telemetry local

Reference: Go Telemetry

Toolchain Improvements

Enhanced go vet

// New warning: Loop variable capture (continued from Go 1.22)
for _, v := range values {
    go func() {
        fmt.Println(v) // No warning (fixed in Go 1.22+)
    }()
}

go mod Improvements

# Improved dependency tree display
go mod graph

# More detailed version information
go version -m ./binary

Performance Improvements

ItemGo 1.22Go 1.23
Compile speedBaseline+3%
PGO effect2-7%2-9%
GC latencyBaseline-5%

PGO (Profile-Guided Optimization)

# Collect profile
go test -cpuprofile=default.pgo -bench=.

# Build with PGO
go build -pgo=auto

Summary

Go 1.23 has achieved important evolution in both language features and toolchain.

  • range over func: Long-awaited iterator feature
  • iter package: Iterator support in standard library
  • unique package: Memory-efficient value canonicalization
  • time.Timer improvements: GC and API improvements
  • Telemetry: Data collection for toolchain improvement

The iterator feature in particular will have a significant impact on Go’s coding style.

← Back to list