From a0e4c0787ede2189b061a9a1d9517f37a0eb73f2 Mon Sep 17 00:00:00 2001 From: Eli Bendersky Date: Wed, 21 Aug 2024 07:27:28 -0700 Subject: [PATCH] Rename range over iterators sample and add a bit more sample --- examples.txt | 2 +- .../range-over-custom-types.hash | 2 - .../range-over-iterators.go} | 29 ++++++- .../range-over-iterators.hash | 2 + .../range-over-iterators.sh} | 6 ++ public/errors | 2 +- public/generics | 4 +- public/index.html | 2 +- ...over-custom-types => range-over-iterators} | 87 ++++++++++++++++--- 9 files changed, 117 insertions(+), 19 deletions(-) delete mode 100644 examples/range-over-custom-types/range-over-custom-types.hash rename examples/{range-over-custom-types/range-over-custom-types.go => range-over-iterators/range-over-iterators.go} (73%) create mode 100644 examples/range-over-iterators/range-over-iterators.hash rename examples/{range-over-custom-types/range-over-custom-types.sh => range-over-iterators/range-over-iterators.sh} (68%) rename public/{range-over-custom-types => range-over-iterators} (70%) diff --git a/examples.txt b/examples.txt index 909ed623a..6f44bd595 100644 --- a/examples.txt +++ b/examples.txt @@ -22,7 +22,7 @@ Interfaces Enums Struct Embedding Generics -Range over Custom Types +Range over Iterators Errors Custom Errors Goroutines diff --git a/examples/range-over-custom-types/range-over-custom-types.hash b/examples/range-over-custom-types/range-over-custom-types.hash deleted file mode 100644 index 76c749245..000000000 --- a/examples/range-over-custom-types/range-over-custom-types.hash +++ /dev/null @@ -1,2 +0,0 @@ -3576a8e614e8e47a0541e800e017d4f9aa2504a3 -q2H-p_moUTy diff --git a/examples/range-over-custom-types/range-over-custom-types.go b/examples/range-over-iterators/range-over-iterators.go similarity index 73% rename from examples/range-over-custom-types/range-over-custom-types.go rename to examples/range-over-iterators/range-over-iterators.go index d578bc301..ea9041dc8 100644 --- a/examples/range-over-custom-types/range-over-custom-types.go +++ b/examples/range-over-iterators/range-over-iterators.go @@ -1,6 +1,6 @@ // Starting with version 1.23, Go has added support for // [iterators](https://go.dev/blog/range-functions), -// which lets us range over custom types. +// which lets us range over pretty much anything! package main @@ -51,6 +51,23 @@ func (lst *List[T]) All() iter.Seq[T] { } } +// Iteration doesn't require an underlying data structure, +// and doesn't even have to be finite! Here's a function +// returning an iterator over Fibonacci numbers: it keeps +// running as long as `yield` keeps returning `true`. +func genFib() iter.Seq[int] { + return func(yield func(int) bool) { + a, b := 1, 1 + + for { + if !yield(a) { + return + } + a, b = b, a+b + } + } +} + func main() { lst := List[int]{} lst.Push(10) @@ -69,4 +86,14 @@ func main() { // all its values into a slice. all := slices.Collect(lst.All()) fmt.Println("all:", all) + + for n := range genFib() { + + // Once the loop hits `break` or an early return, the `yield` function + // passed to the iterator will return `false`. + if n >= 10 { + break + } + fmt.Println(n) + } } diff --git a/examples/range-over-iterators/range-over-iterators.hash b/examples/range-over-iterators/range-over-iterators.hash new file mode 100644 index 000000000..ee781b407 --- /dev/null +++ b/examples/range-over-iterators/range-over-iterators.hash @@ -0,0 +1,2 @@ +375f830fbe82633900d572c9077302143463a2e3 +BayyagaCK83 diff --git a/examples/range-over-custom-types/range-over-custom-types.sh b/examples/range-over-iterators/range-over-iterators.sh similarity index 68% rename from examples/range-over-custom-types/range-over-custom-types.sh rename to examples/range-over-iterators/range-over-iterators.sh index cb58fdcf2..7fa2b5918 100644 --- a/examples/range-over-custom-types/range-over-custom-types.sh +++ b/examples/range-over-iterators/range-over-iterators.sh @@ -2,4 +2,10 @@ 13 23 all: [10 13 23] +1 +1 +2 +3 +5 +8 diff --git a/public/errors b/public/errors index e1e00982f..5830d24be 100644 --- a/public/errors +++ b/public/errors @@ -12,7 +12,7 @@ } if (e.key == "ArrowLeft") { - window.location.href = 'range-over-custom-types'; + window.location.href = 'range-over-iterators'; } diff --git a/public/generics b/public/generics index 5758c6c45..a0d8bb294 100644 --- a/public/generics +++ b/public/generics @@ -17,7 +17,7 @@ if (e.key == "ArrowRight") { - window.location.href = 'range-over-custom-types'; + window.location.href = 'range-over-iterators'; } } @@ -225,7 +225,7 @@ automatically.

- Next example: Range over Custom Types. + Next example: Range over Iterators.

diff --git a/public/index.html b/public/index.html index 40e33b1ad..21de726ca 100644 --- a/public/index.html +++ b/public/index.html @@ -81,7 +81,7 @@

Go by Example

  • Generics
  • -
  • Range over Custom Types
  • +
  • Range over Iterators
  • Errors
  • diff --git a/public/range-over-custom-types b/public/range-over-iterators similarity index 70% rename from public/range-over-custom-types rename to public/range-over-iterators index ddbd0a922..4cec9ff57 100644 --- a/public/range-over-custom-types +++ b/public/range-over-iterators @@ -2,7 +2,7 @@ - Go by Example: Range over Custom Types + Go by Example: Range over Iterators -
    -

    Go by Example: Range over Custom Types

    +
    +

    Go by Example: Range over Iterators

    @@ -32,7 +32,7 @@ @@ -147,6 +147,39 @@ return value for a potential early termination.

    + + + + + + + + + + - + + + + + + + + + + @@ -204,7 +263,13 @@ all its values into a slice.

    10
     13
     23
    -all: [10 13 23]
    +all: [10 13 23] +1 +1 +2 +3 +5 +8 @@ -223,7 +288,7 @@ all its values into a slice.

    Starting with version 1.23, Go has added support for iterators, -which lets us range over custom types.

    +which lets us range over pretty much anything!

    @@ -46,7 +46,7 @@ which lets us range over custom types.

    - +
    package main
    +

    Iteration doesn’t require an underlying data structure, +and doesn’t even have to be finite! Here’s a function +returning an iterator over Fibonacci numbers: it keeps +running as long as yield keeps returning true.

    + +
    + +
    func genFib() iter.Seq[int] {
    +    return func(yield func(int) bool) {
    +        a, b := 1, 1
    +
    + + + +
            for {
    +            if !yield(a) {
    +                return
    +            }
    +            a, b = b, a+b
    +        }
    +    }
    +}
    +
    @@ -163,8 +196,8 @@ return value for a potential early termination.

    -

    Since List.All returns an interator, it can be used -in a regular range loop!

    +

    Since List.All returns an iterator, we can use it +in a regular range loop.

    @@ -183,10 +216,36 @@ For example, Collect takes any iterator and collects all its values into a slice.

    +
        all := slices.Collect(lst.All())
    -    fmt.Println("all:", all)
    +    fmt.Println("all:", all)
    +
    + + + +
        for n := range genFib() {
    +
    +

    Once the loop hits break or an early return, the yield function +passed to the iterator will return false, stopping the iterator.

    + +
    + +
            if n >= 10 {
    +            break
    +        }
    +        fmt.Println(n)
    +    }
     }