Înainte de Go 1.22, dacă aveați o colecție complexă (cum ar fi un arbore binar, o listă înlănțuită sau un flux de date) și doreați să o parcurgeți într-o buclă for ... range, erați obligat să alocați un slice intermediar complet pe heap sau să implementați canale concurente lente. Mecanismul Range-over-Func (definitivat în Go 1.23 prin pachetul iter) permite buclelor for range să itereze direct peste funcții de tip iterator cu zero alocări de memorie.
Definirea unui iterator Push cu iter.Seq2
package main
import (
"fmt"
"iter"
)
// Definim un arbore binar simplu:
type Nod struct {
Valoare int
Stanga *Nod
Dreapta *Nod
}
// Iterator Push (In-Order Traversal) compatibil direct cu bucla for range:
func (n *Nod) ToateValorile() iter.Seq[int] {
return func(yield func(int) bool) {
var parcurge func(*Nod) bool
parcurge = func(curent *Nod) bool {
if curent == nil {
return true
}
if !parcurge(curent.Stanga) { return false }
if !yield(curent.Valoare) { return false } // Dacă bucla dă 'break', yield returnează false!
return parcurge(curent.Dreapta)
}
parcurge(n)
}
}
func main() {
radacina := &Nod{
Valoare: 20,
Stanga: &Nod{Valoare: 10},
Dreapta: &Nod{Valoare: 30},
}
// Iterație curată direct peste structura arborescentă fără alocare de memorie:
for v := range radacina.ToateValorile() {
fmt.Printf("%d ", v) // Afișează: 10 20 30
}
fmt.Println("")
}