Documentation
¶
Overview ¶
Package iter defines an iterator interface, a collection of concrete iterator types, and some functions for operating on iterators. It is also a drop-in replacement for the Go 1.23 standard library package iter (a preview of which is available in Go 1.22 when building with GOEXPERIMENT=rangefunc).
Index ¶
- func LastN[T any](inp Of[T], n int) ([]T, error)
- func Page[F ~func(S, bool) error, S ~[]T, T any](inp Of[T], pageSize int, f F) error
- func ToChan[T any](inp Of[T]) (<-chan T, func() error)
- func ToChanContext[T any](ctx context.Context, inp Of[T]) (<-chan T, func() error)
- func ToMap[K comparable, V any](inp Of[Pair[K, V]]) (map[K]V, error)
- func ToSlice[T any](iter Of[T]) ([]T, error)
- type Of
- func Accum[F ~func(T, T) T, T any](inp Of[T], f F) Of[T]
- func Accumx[F ~func(T, T) (T, error), T any](inp Of[T], f F) Of[T]
- func Concat[T any](inps ...Of[T]) Of[T]
- func Dup[T any](inp Of[T], n int) []Of[T]
- func Filter[F ~func(T) bool, T any](inp Of[T], f F) Of[T]
- func FirstN[T any](inp Of[T], n int) Of[T]
- func From[T any](items ...T) Of[T]
- func FromChan[T any](ch <-chan T, opts ...Option) Of[T]
- func FromMap[M ~map[K]V, K comparable, V any](m M) Of[Pair[K, V]]
- func FromMapKeys[M ~map[K]V, K comparable, V any](m M) Of[K]
- func FromSeq[T any](seq Seq[T]) Of[T]
- func FromSeq2[T, U any](seq Seq2[T, U]) Of[Pair[T, U]]
- func FromSeq2Context[T, U any](ctx context.Context, seq Seq2[T, U]) Of[Pair[T, U]]
- func FromSeqContext[T any](ctx context.Context, seq Seq[T]) Of[T]
- func FromSlice[S ~[]T, T any](s S) Of[T]
- func Gen[F ~func() (T, bool, error), T any](f F) Of[T]
- func Go[F ~func(chan<- T) error, T any](f F) Of[T]
- func Ints(start, delta int) Of[int]
- func Lines(r io.Reader) Of[string]
- func LongLines(ctx context.Context, r io.Reader) Of[io.Reader]
- func Map[F ~func(T) U, T, U any](inp Of[T], f F) Of[U]
- func Mapx[F ~func(T) (U, error), T, U any](inp Of[T], f F) Of[U]
- func Prepared[T any](ctx context.Context, stmt *sql.Stmt, args ...any) (Of[T], error)
- func Repeat[T any](val T) Of[T]
- func SQL[T any](ctx context.Context, db QueryerContext, query string, args ...any) (Of[T], error)
- func SkipN[T any](inp Of[T], n int) Of[T]
- func SkipUntil[F ~func(T) bool, T any](inp Of[T], f F) Of[T]
- func Zip[T, U any](t Of[T], u Of[U]) Of[Pair[T, U]]
- type Option
- type Pair
- type QueryerContext
- type Seq
- type Seq2
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func LastN ¶
LastN produces a slice containing the last n elements of the input iterator (or all of the input, if there are fewer than n elements). There is no guarantee that any elements will ever be produced: the input iterator may be infinite!
func Page ¶
Page consumes inp one "page" at a time of up to pageSize elements, repeatedly calling a callback with a slice of the items consumed. The callback also gets a second argument that is false until the final call, when it is true.
An error from the callback will terminate Page and return that error.
The space for the slice is reused on each call to the callback.
The slice in every non-final call of the callback is guaranteed to have a length of pageSize. The final call of the callback may contain an empty slice.
Example ¶
package main import ( "fmt" "github.com/bobg/go-generics/v3/iter" ) func main() { var ( ints = iter.Ints(1, 1) // All integers starting at 1 first10 = iter.FirstN(ints, 10) // First 10 integers ) err := iter.Page(first10, 3, func(page []int, final bool) error { fmt.Println(page, final) return nil }) if err != nil { panic(err) } }
Output: [1 2 3] false [4 5 6] false [7 8 9] false [10] true
func ToChan ¶
ToChan creates a Go channel and copies the contents of an iterator to it. The second return value is a function that may be called after the channel is closed to inspect any error that occurred.
func ToChanContext ¶
ToChanContext creates a Go channel and copies the contents of an iterator to it. The second return value is a function that may be called after the channel is closed to inspect any error that occurred. The channel will close early if the context is canceled (and the error-returning function will indicate that).
func ToMap ¶
func ToMap[K comparable, V any](inp Of[Pair[K, V]]) (map[K]V, error)
ToMap consumes an iterator of key-value pairs and produces a Go map of the values. All but the last of any pairs with duplicate keys are discarded. Be careful! The input may be very long or even infinite. Consider using FirstN to ensure the input has a reasonable size.
Types ¶
type Of ¶
type Of[T any] interface { // Next advances the iterator to its next value and tells whether one is available to read. // A true result is necessary before calling Val. // Once Next returns false, it must continue returning false. Next() bool // Val returns the current value of the iterator. // Callers must get a true result from Next before calling Val. // Repeated calls to Val // with no intervening call to Next // should return the same value. Val() T // Err returns the error that this iterator's source encountered during iteration, if any. // It may be called only after Next returns false. Err() error }
Of is the interface implemented by iterators. It is called "Of" so that when qualified with this package name and instantiated with a member type, it reads naturally: e.g., iter.Of[int].
func Accum ¶
Accum accumulates the result of repeatedly applying a simple function to the elements of an iterator. If inp[i] is the ith element of the input and out[i] is the ith element of the output, then:
out[0] == inp[0]
and
out[i+1] == f(out[i], inp[i+1])
Example ¶
package main import ( "fmt" "github.com/bobg/go-generics/v3/iter" ) func main() { var ( ints = iter.Ints(1, 1) // All integers starting at 1 first5 = iter.FirstN(ints, 5) // First 5 integers sums = iter.Accum(first5, func(a, b int) int { return a + b }) ) for sums.Next() { fmt.Println(sums.Val()) } if err := sums.Err(); err != nil { panic(err) } }
Output: 1 3 6 10 15
func Accumx ¶
Accumx is the extended form of Accum. It accumulates the result of repeatedly applying a function to the elements of an iterator. If inp[i] is the ith element of the input and out[i] is the ith element of the output, then:
out[0] == inp[0]
and
out[i+1] == f(out[i], inp[i+1])
func Dup ¶
Dup duplicates the contents of an iterator, producing n new iterators, each containing the members of the original.
An internal buffer grows to roughly the size of the difference between the output iterator that is farthest ahead in the stream, and the one that is farthest behind.
Example ¶
package main import ( "fmt" "github.com/bobg/go-generics/v3/iter" ) func main() { var ( ints = iter.Ints(1, 1) // All integers starting at 1 first10 = iter.FirstN(ints, 10) // First 10 integers dups = iter.Dup(first10, 2) // Two copies of the first10 iterator evens = iter.Filter(dups[0], func(val int) bool { return val%2 == 0 }) odds = iter.Filter(dups[1], func(val int) bool { return val%2 == 1 }) ) evensSlice, err := iter.ToSlice(evens) if err != nil { panic(err) } fmt.Println(evensSlice) oddsSlice, err := iter.ToSlice(odds) if err != nil { panic(err) } fmt.Println(oddsSlice) }
Output: [2 4 6 8 10] [1 3 5 7 9]
func Filter ¶
Filter copies the input iterator to the output, including only those elements that cause f to return true.
func FirstN ¶
FirstN produces an iterator containing the first n elements of the input (or all of the input, if there are fewer than n elements). Remaining elements of the input are not consumed. It is the caller's responsibility to release any associated resources.
func FromChan ¶
FromChan copies a Go channel to an iterator. If the WithContext option is given, copying will end early if the given context is canceled (and the iterator's Err function will indicate that). If the WithError option is given, it is called after the channel closes to determine the value of the iterator's Err function.
func FromMap ¶
func FromMap[M ~map[K]V, K comparable, V any](m M) Of[Pair[K, V]]
FromMap produces an iterator of key-value pairs from a Go map. The resulting iterator never returns an error. Note that this is implemented in terms of FromMapKeys, which makes copies the keys of the map to a new slice.
Example ¶
package main import ( "fmt" "github.com/bobg/go-generics/v3/iter" ) func main() { m := map[string]int{ "one": 1, "two": 2, "three": 3, } it := iter.FromMap(m) for it.Next() { val := it.Val() fmt.Println(val.X, val.Y) } if err := it.Err(); err != nil { panic(err) } }
Output: one 1 two 2 three 3
func FromMapKeys ¶
func FromMapKeys[M ~map[K]V, K comparable, V any](m M) Of[K]
FromMapKeys produces an iterator over the keys of a Go map. Note that this is implemented in terms of FromSlice, after first copying the keys of the map to a new slice.
func FromSeq2Context ¶ added in v3.4.0
FromSeq2Context converts a Go 1.23 pair iterator into an Of[Pair[T, U]].
func FromSeqContext ¶ added in v3.4.0
FromSeqContext converts a Go 1.23 iterator into an Of[T].
func Gen ¶
Gen produces an iterator of values obtained by repeatedly calling f. If f returns an error, iteration stops and the error is available via the iterator's Err method. Otherwise, each call to f should return a value and a true boolean. When f returns a false boolean, it signals the normal end of iteration.
func Go ¶
Go runs a function in a goroutine and returns an iterator over the values it produces. The function receives a channel for producing values. The channel closes when the function exits. Any error produced by the function is the value of the iterator's Err method.
Example ¶
package main import ( "fmt" "github.com/bobg/go-generics/v3/iter" ) func main() { it := iter.Go(func(ch chan<- int) error { ch <- 1 ch <- 2 ch <- 3 return nil }) slice, err := iter.ToSlice(it) if err != nil { panic(err) } fmt.Println(slice) }
Output: [1 2 3]
func Ints ¶
Ints produces an infinite iterator over integers beginning at start, with each element increasing by delta.
func Lines ¶
Lines produces an iterator over the lines of text in r. This uses a bufio.Scanner and is subject to its default line-length limit (see https://pkg.go.dev/bufio#pkg-constants).
func LongLines ¶ added in v3.3.0
LongLines produces an iterator of readers, each delivering a single line of text from r. Unlike Lines, this does not use a bufio.Scanner and is not subject to its default line-length limit. Each reader must be fully consumed before the next one is available. If not consuming all readers from the iterator, the caller should cancel the context to reclaim resources.
func Map ¶
Map produces an iterator of values transformed from an input iterator by a simple mapping function.
func Mapx ¶
Mapx is the extended form of Map. It produces an iterator of values transformed from an input iterator by a mapping function. If the mapping function returns an error, iteration stops and the error is available via the output iterator's Err method.
func Prepared ¶ added in v3.1.0
Prepared is like SQL but uses a prepared sql.Stmt instead of a database and string query. It is the caller's responsibility to close the statement.
func SQL ¶
SQL performs a query against db and returns the results as an iterator of type T.
If the query produces a single value per row, T may be any scalar type (bool, int, float, string) into which the values can be scanned.
Otherwise T must be a struct type whose fields have the same types, in the same order, as the values being queried. The values produced by the iterator will be instances of that struct type, with fields populated by the queried values.
func SkipUntil ¶
SkipUntil copies the input iterator to the output, discarding the initial elements until the first one that causes f to return true. That element and the remaining elements of inp are included in the output, and f is not called again.
func Zip ¶
Zip takes two iterators and produces a new iterator containing pairs of corresponding elements. If one input iterator ends before the other, Zip produces zero values of the appropriate type in constructing pairs.
Example ¶
package main import ( "fmt" "github.com/bobg/go-generics/v3/iter" ) func main() { var ( letters = iter.FromSlice([]string{"a", "b", "c", "d"}) nums = iter.FromSlice([]int{1, 2, 3}) pairs = iter.Zip(letters, nums) ) for pairs.Next() { val := pairs.Val() fmt.Println(val.X, val.Y) } if err := pairs.Err(); err != nil { panic(err) } }
Output: a 1 b 2 c 3 d 0
type Option ¶
type Option func(*chanIterConf)
Option is the type of options that can be passed to FromChan.
func WithContext ¶
WithContext associates a context option with a channel iterator.
type QueryerContext ¶
type QueryerContext interface {
QueryContext(context.Context, string, ...interface{}) (*sql.Rows, error)
}
QueryerContext is a minimal interface satisfied by *sql.DB (from database/sql).
type Seq ¶ added in v3.2.0
Seq is a Go 1.23 iterator over sequences of individual values. When called as seq(yield), seq calls yield(v) for each value v in the sequence, stopping early if yield returns false.
This type is defined in the same way as in the standard library, but is not identical, because Go type aliases cannot (yet?) be used with generic types.
func All ¶ added in v3.2.0
All makes a Go 1.23 iterator from an Of[T], suitable for use in a one-variable for-range loop. To try this in Go 1.22, build with the environment variable GOEXPERIMENT set to rangefunc. See https://go.dev/wiki/RangefuncExperiment.
The caller should still check the iterator's Err method after the loop terminates.
type Seq2 ¶ added in v3.2.0
Seq2 is a Go 1.23 iterator over sequences of pairs of values, most commonly key-value pairs. When called as seq(yield), seq calls yield(k, v) for each pair (k, v) in the sequence, stopping early if yield returns false.
This type is defined in the same way as in the standard library, but is not identical, because Go type aliases cannot (yet?) be used with generic types.
func AllCount ¶ added in v3.2.0
AllCount makes a Go 1.23 counting iterator from an Of[T], suitable for use in a two-variable for-range loop. To try this in Go 1.22, build with the environment variable GOEXPERIMENT set to rangefunc. See https://go.dev/wiki/RangefuncExperiment.
The caller should still check the iterator's Err method after the loop terminates.
func AllPairs ¶ added in v3.2.0
AllPairs makes a Go 1.23 pair iterator from an Of[Pair[T, U]], suitable for use in a two-variable for-range loop. To try this in Go 1.22, build with the environment variable GOEXPERIMENT set to rangefunc. See https://go.dev/wiki/RangefuncExperiment.
The caller should still check the iterator's Err method after the loop terminates.