Go 1.23 - Iteradores y Telemetría

2025.12.12

Resumen de Go 1.23

Go 1.23, lanzado en agosto de 2024, introduce la función de iteradores (range over func) tan esperada, y se han añadido muchas mejoras a la biblioteca estándar.

Referencia: Go 1.23 Release Notes

range over func (Iteradores)

Uso básico

Ahora es posible iterar directamente sobre funciones en bucles for.

package main

import "fmt"

// Definir función iteradora
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"}

    // Usar el iterador
    for v := range Backward(s) {
        fmt.Println(v) // c, b, a
    }
}

Paquete iter

Se ha añadido el nuevo paquete estándar iter.

import "iter"

// Seq: Secuencia de valores
type Seq[V any] func(yield func(V) bool)

// Seq2: Secuencia de pares clave-valor
type Seq2[K, V any] func(yield func(K, V) bool)

// Pull: Convertir estilo push a estilo pull
func Pull[V any](seq Seq[V]) (next func() (V, bool), stop func())

Extensiones del paquete slices

import "slices"

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

// All: Iterar todos los elementos
for i, v := range slices.All(s) {
    fmt.Printf("index: %d, value: %d\n", i, v)
}

// Backward: Iterar en orden inverso
for i, v := range slices.Backward(s) {
    fmt.Println(i, v)
}

// Values: Solo valores sin índice
for v := range slices.Values(s) {
    fmt.Println(v)
}

// Chunk: Dividir en grupos de n
for chunk := range slices.Chunk(s, 2) {
    fmt.Println(chunk) // [1 2], [3 4], [5]
}

Referencia: Go iter package

Extensiones del paquete maps

import "maps"

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

// Keys: Iterador de claves
for k := range maps.Keys(m) {
    fmt.Println(k)
}

// Values: Iterador de valores
for v := range maps.Values(m) {
    fmt.Println(v)
}

// All: Iterador de claves y valores
for k, v := range maps.All(m) {
    fmt.Printf("%s: %d\n", k, v)
}

// Insert: Insertar en el mapa desde un iterador
maps.Insert(m, slices.All([]struct{k string; v int}{{"d", 4}}))

Paquete unique

Proporciona normalización de valores (interning) eficiente en memoria.

import "unique"

// Normalización de cadenas
h1 := unique.Make("hello")
h2 := unique.Make("hello")

// La misma cadena devuelve el mismo handle
fmt.Println(h1 == h2) // true

// Obtener el valor
fmt.Println(h1.Value()) // "hello"

// Se puede usar con cualquier tipo comparable
type Point struct{ X, Y int }
p1 := unique.Make(Point{1, 2})
p2 := unique.Make(Point{1, 2})
fmt.Println(p1 == p2) // true

Referencia: Go unique package

Mejoras en time.Timer

Se ha mejorado el comportamiento del recolector de basura y los canales.

import "time"

// Los Timer no utilizados se recolectan automáticamente por el GC
timer := time.NewTimer(time.Hour)
// Se recolecta por GC sin necesidad de llamar timer.Stop()

// Mejora en el comportamiento de Reset
timer = time.NewTimer(time.Second)
if !timer.Stop() {
    // Go 1.23: El canal se drena automáticamente
    // Antes: Era necesario <-timer.C
}
timer.Reset(time.Minute)

Paquete structs (Experimental)

Permite controlar el diseño de las estructuras.

import "structs"

type Data struct {
    _     structs.HostLayout  // Usar el diseño del host
    Value int64
}

Telemetría

Se ha añadido funcionalidad para recopilar datos de uso de la cadena de herramientas de Go.

# Verificar estado de telemetría
go telemetry

# Activar telemetría (opt-in)
go telemetry on

# Desactivar telemetría
go telemetry off

# Solo local (sin carga)
go telemetry local

Referencia: Go Telemetry

Mejoras en la cadena de herramientas

Mejoras en go vet

// Nueva advertencia: Captura de variable de bucle (continúa desde Go 1.22)
for _, v := range values {
    go func() {
        fmt.Println(v) // Sin advertencia (corregido en Go 1.22+)
    }()
}

Mejoras en go mod

# Mejora en la visualización del árbol de dependencias
go mod graph

# Información de versión más detallada
go version -m ./binary

Mejoras de rendimiento

ElementoGo 1.22Go 1.23
Velocidad de compilaciónBase+3%
Efecto PGO2-7%2-9%
Latencia GCBase-5%

PGO (Profile-Guided Optimization)

# Recopilar perfil
go test -cpuprofile=default.pgo -bench=.

# Compilar usando PGO
go build -pgo=auto

Resumen

Go 1.23 ha logrado avances importantes tanto en características del lenguaje como en la cadena de herramientas.

  • range over func: La esperada función de iteradores
  • Paquete iter: Soporte de iteradores en la biblioteca estándar
  • Paquete unique: Normalización de valores eficiente en memoria
  • Mejoras en time.Timer: Mejoras en GC y API
  • Telemetría: Recopilación de datos para mejorar la cadena de herramientas

La función de iteradores en particular tendrá un gran impacto en el estilo de código de Go.

← Volver a la lista