Memo
Go Weekly #2: Go 1.23 Iterators
Why People are Angry over Go 1.23 Iterators
Context:
- Most languages provide standardized way to iterate over values stored in containers.
Problem:
Go has
forrangefor maps, slices, strings, arrays and channels but no generic mechanism for user-written containers.Short list of some non-generic iterators:
runtime.CallersFrames: returns
runtime.Framesiterates over stack frames;Frameshas aNextmethod and a bool to check if there are more frames.bufio.Scanner: iterates through an
io.Reader;Scanmethod advances to the next value,Bytesmethod to return the value andErrto return error.database/sql.Rows: iterates through the results of a query; also has
Scanmethod.
Before Generics were introduced, no way to write an interface that described an iterator that would cover all of the use cases…
Solution:
- Go 1.22 proposal of adding package
itercan range over integers and functions:
type ( Seq[V any] func(yield func(V) bool) bool Seq2[K, V any] func(yield func(K, V) bool) bool )(Seq2 represents a sequence of paired values: key-value, index-value or value-error)
- An iterator is a function that passes successive elements of a sequence to a callback function
yield, it returns true if it should continue, false if it should stop.
type ( Yield[V any] func(V bool) Yield2[K, V any] func(K,V) bool )- Examples:
func Backward[E any](s []E) func(func(int, E) bool) { return func(yield func(int, E) bool) { for i := len(s)-1; i >= 0; i-- { if !yield(i, s[i]) { // Where clean-up code goes return } } } } s := []string{"a", "b", "c"} for _, el in range Backward(s) { fmt.Print(el, " ") } // c b a- Go 1.22 proposal of adding package
Conclusion:
- The
for rangeis getting complex:- return true => continue
- return false => break
- Feels too functional than an imperative language
- Still the purpose is good, let’s wait to see the adoption in community after awhile
- The
Mentioned in
Subscribe to Dwarves Memo
Receive the latest updates directly to your inbox.
Go Weekly #2: Go 1.23 Iterators

