Source file src/iter/example_test.go

     1  // Copyright 2026 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package iter_test
     6  
     7  import (
     8  	"fmt"
     9  	"iter"
    10  	"slices"
    11  	"strings"
    12  )
    13  
    14  func ExampleSeq() {
    15  	// A Seq is a function that passes each value of a sequence to
    16  	// yield. Nothing requires the sequence to be finite: this one ends
    17  	// only when yield reports that the consumer has stopped, which
    18  	// happens when the range loop below breaks.
    19  	var fib iter.Seq[int] = func(yield func(int) bool) {
    20  		a, b := 0, 1
    21  		for yield(a) {
    22  			a, b = b, a+b
    23  		}
    24  	}
    25  
    26  	for n := range fib {
    27  		if n > 50 {
    28  			break
    29  		}
    30  		fmt.Print(n, " ")
    31  	}
    32  	fmt.Println()
    33  
    34  	// Output:
    35  	// 0 1 1 2 3 5 8 13 21 34
    36  }
    37  
    38  func ExampleSeq2() {
    39  	// A Seq2 passes a pair of values per element, here the two halves
    40  	// of a key=value field. Ranging over an existing Seq, in this case
    41  	// strings.SplitSeq, keeps the fields from being collected into a
    42  	// slice first.
    43  	var attrs iter.Seq2[string, string] = func(yield func(string, string) bool) {
    44  		for field := range strings.SplitSeq("gopher=blue,size=large,tail", ",") {
    45  			k, v, _ := strings.Cut(field, "=")
    46  			if !yield(k, v) {
    47  				return
    48  			}
    49  		}
    50  	}
    51  
    52  	for k, v := range attrs {
    53  		fmt.Printf("%q %q\n", k, v)
    54  	}
    55  
    56  	// Output:
    57  	// "gopher" "blue"
    58  	// "size" "large"
    59  	// "tail" ""
    60  }
    61  
    62  func ExamplePull() {
    63  	// Merging two sorted sequences means advancing whichever one holds
    64  	// the smaller value, so the two have to move independently. A range
    65  	// loop cannot do that, since it drives a single sequence from start
    66  	// to finish. Pull converts each sequence into a next function that
    67  	// produces one value per call.
    68  	next1, stop1 := iter.Pull(slices.Values([]int{1, 3, 5, 7}))
    69  	defer stop1()
    70  	next2, stop2 := iter.Pull(slices.Values([]int{2, 3, 6}))
    71  	defer stop2()
    72  
    73  	v1, ok1 := next1()
    74  	v2, ok2 := next2()
    75  	for ok1 || ok2 {
    76  		if !ok2 || ok1 && v1 <= v2 {
    77  			fmt.Print(v1, " ")
    78  			v1, ok1 = next1()
    79  		} else {
    80  			fmt.Print(v2, " ")
    81  			v2, ok2 = next2()
    82  		}
    83  	}
    84  	fmt.Println()
    85  
    86  	// Output:
    87  	// 1 2 3 3 5 6 7
    88  }
    89  
    90  func ExamplePull2() {
    91  	// This caller reads only the first two pairs and leaves the rest of
    92  	// the sequence unread. Because the sequence is not consumed to
    93  	// completion, stop has to be called to let the iterator function
    94  	// finish and return.
    95  	next, stop := iter.Pull2(slices.All([]string{"hydrogen", "helium", "lithium"}))
    96  	defer stop()
    97  
    98  	for range 2 {
    99  		i, element, ok := next()
   100  		if !ok {
   101  			break
   102  		}
   103  		fmt.Println(i, element)
   104  	}
   105  
   106  	// Output:
   107  	// 0 hydrogen
   108  	// 1 helium
   109  }
   110  

View as plain text