blob: 6ed82c84c8cf8e823895ce7a86e418aeac975179 [file]
// Copyright 2026 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package iter_test
import (
"fmt"
"iter"
"slices"
"strings"
)
func ExampleSeq() {
// A Seq is a function that passes each value of a sequence to
// yield. Nothing requires the sequence to be finite: this one ends
// only when yield reports that the consumer has stopped, which
// happens when the range loop below breaks.
var fib iter.Seq[int] = func(yield func(int) bool) {
a, b := 0, 1
for yield(a) {
a, b = b, a+b
}
}
for n := range fib {
if n > 50 {
break
}
fmt.Print(n, " ")
}
fmt.Println()
// Output:
// 0 1 1 2 3 5 8 13 21 34
}
func ExampleSeq2() {
// A Seq2 passes a pair of values per element, here the two halves
// of a key=value field. Ranging over an existing Seq, in this case
// strings.SplitSeq, keeps the fields from being collected into a
// slice first.
var attrs iter.Seq2[string, string] = func(yield func(string, string) bool) {
for field := range strings.SplitSeq("gopher=blue,size=large,tail", ",") {
k, v, _ := strings.Cut(field, "=")
if !yield(k, v) {
return
}
}
}
for k, v := range attrs {
fmt.Printf("%q %q\n", k, v)
}
// Output:
// "gopher" "blue"
// "size" "large"
// "tail" ""
}
func ExamplePull() {
// Merging two sorted sequences means advancing whichever one holds
// the smaller value, so the two have to move independently. A range
// loop cannot do that, since it drives a single sequence from start
// to finish. Pull converts each sequence into a next function that
// produces one value per call.
next1, stop1 := iter.Pull(slices.Values([]int{1, 3, 5, 7}))
defer stop1()
next2, stop2 := iter.Pull(slices.Values([]int{2, 3, 6}))
defer stop2()
v1, ok1 := next1()
v2, ok2 := next2()
for ok1 || ok2 {
if !ok2 || ok1 && v1 <= v2 {
fmt.Print(v1, " ")
v1, ok1 = next1()
} else {
fmt.Print(v2, " ")
v2, ok2 = next2()
}
}
fmt.Println()
// Output:
// 1 2 3 3 5 6 7
}
func ExamplePull2() {
// This caller reads only the first two pairs and leaves the rest of
// the sequence unread. Because the sequence is not consumed to
// completion, stop has to be called to let the iterator function
// finish and return.
next, stop := iter.Pull2(slices.All([]string{"hydrogen", "helium", "lithium"}))
defer stop()
for range 2 {
i, element, ok := next()
if !ok {
break
}
fmt.Println(i, element)
}
// Output:
// 0 hydrogen
// 1 helium
}