Rename range over iterators sample and add a bit more sample

This commit is contained in:
Eli Bendersky
2024-08-21 07:27:28 -07:00
parent 4d27fb58cf
commit a0e4c0787e
9 changed files with 117 additions and 19 deletions

View File

@@ -22,7 +22,7 @@ Interfaces
Enums
Struct Embedding
Generics
Range over Custom Types
Range over Iterators
Errors
Custom Errors
Goroutines

View File

@@ -1,2 +0,0 @@
3576a8e614e8e47a0541e800e017d4f9aa2504a3
q2H-p_moUTy

View File

@@ -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)
}
}

View File

@@ -0,0 +1,2 @@
375f830fbe82633900d572c9077302143463a2e3
BayyagaCK83

2
public/errors generated
View File

@@ -12,7 +12,7 @@
}
if (e.key == "ArrowLeft") {
window.location.href = 'range-over-custom-types';
window.location.href = 'range-over-iterators';
}

4
public/generics generated
View File

@@ -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.</p>
<p class="next">
Next example: <a href="range-over-custom-types">Range over Custom Types</a>.
Next example: <a href="range-over-iterators">Range over Iterators</a>.
</p>

2
public/index.html generated
View File

@@ -81,7 +81,7 @@
<li><a href="generics">Generics</a></li>
<li><a href="range-over-custom-types">Range over Custom Types</a></li>
<li><a href="range-over-iterators">Range over Iterators</a></li>
<li><a href="errors">Errors</a></li>

View File

@@ -2,7 +2,7 @@
<html>
<head>
<meta charset="utf-8">
<title>Go by Example: Range over Custom Types</title>
<title>Go by Example: Range over Iterators</title>
<link rel=stylesheet href="site.css">
</head>
<script>
@@ -23,8 +23,8 @@
}
</script>
<body>
<div class="example" id="range-over-custom-types">
<h2><a href="./">Go by Example</a>: Range over Custom Types</h2>
<div class="example" id="range-over-iterators">
<h2><a href="./">Go by Example</a>: Range over Iterators</h2>
<table>
@@ -32,7 +32,7 @@
<td class="docs">
<p>Starting with version 1.23, Go has added support for
<a href="https://go.dev/blog/range-functions">iterators</a>,
which lets us range over custom types.</p>
which lets us range over pretty much anything!</p>
</td>
<td class="code empty leading">
@@ -46,7 +46,7 @@ which lets us range over custom types.</p>
</td>
<td class="code leading">
<a href="https://go.dev/play/p/q2H-p_moUTy"><img title="Run code" src="play.png" class="run" /></a><img title="Copy code" src="clipboard.png" class="copy" />
<a href="https://go.dev/play/p/BayyagaCK83"><img title="Run code" src="play.png" class="run" /></a><img title="Copy code" src="clipboard.png" class="copy" />
<pre class="chroma"><code><span class="line"><span class="cl"><span class="kn">package</span> <span class="nx">main</span></span></span></code></pre>
</td>
</tr>
@@ -147,6 +147,39 @@ return value for a potential early termination.</p>
</td>
</tr>
<tr>
<td class="docs">
<p>Iteration doesn&rsquo;t require an underlying data structure,
and doesn&rsquo;t even have to be finite! Here&rsquo;s a function
returning an iterator over Fibonacci numbers: it keeps
running as long as <code>yield</code> keeps returning <code>true</code>.</p>
</td>
<td class="code leading">
<pre class="chroma"><code><span class="line"><span class="cl"><span class="kd">func</span> <span class="nf">genFib</span><span class="p">()</span> <span class="nx">iter</span><span class="p">.</span><span class="nx">Seq</span><span class="p">[</span><span class="kt">int</span><span class="p">]</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="kd">func</span><span class="p">(</span><span class="nx">yield</span> <span class="kd">func</span><span class="p">(</span><span class="kt">int</span><span class="p">)</span> <span class="kt">bool</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">a</span><span class="p">,</span> <span class="nx">b</span> <span class="o">:=</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span></span></span></code></pre>
</td>
</tr>
<tr>
<td class="docs">
</td>
<td class="code leading">
<pre class="chroma"><code><span class="line"><span class="cl"> <span class="k">for</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">!</span><span class="nf">yield</span><span class="p">(</span><span class="nx">a</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="nx">a</span><span class="p">,</span> <span class="nx">b</span> <span class="p">=</span> <span class="nx">b</span><span class="p">,</span> <span class="nx">a</span><span class="o">+</span><span class="nx">b</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre>
</td>
</tr>
<tr>
<td class="docs">
@@ -163,8 +196,8 @@ return value for a potential early termination.</p>
<tr>
<td class="docs">
<p>Since <code>List.All</code> returns an interator, it can be used
in a regular <code>range</code> loop!</p>
<p>Since <code>List.All</code> returns an iterator, we can use it
in a regular <code>range</code> loop.</p>
</td>
<td class="code leading">
@@ -183,10 +216,36 @@ For example, <code>Collect</code> takes any iterator and collects
all its values into a slice.</p>
</td>
<td class="code">
<td class="code leading">
<pre class="chroma"><code><span class="line"><span class="cl"> <span class="nx">all</span> <span class="o">:=</span> <span class="nx">slices</span><span class="p">.</span><span class="nf">Collect</span><span class="p">(</span><span class="nx">lst</span><span class="p">.</span><span class="nf">All</span><span class="p">())</span>
</span></span><span class="line"><span class="cl"> <span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;all:&#34;</span><span class="p">,</span> <span class="nx">all</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;all:&#34;</span><span class="p">,</span> <span class="nx">all</span><span class="p">)</span></span></span></code></pre>
</td>
</tr>
<tr>
<td class="docs">
</td>
<td class="code leading">
<pre class="chroma"><code><span class="line"><span class="cl"> <span class="k">for</span> <span class="nx">n</span> <span class="o">:=</span> <span class="k">range</span> <span class="nf">genFib</span><span class="p">()</span> <span class="p">{</span></span></span></code></pre>
</td>
</tr>
<tr>
<td class="docs">
<p>Once the loop hits <code>break</code> or an early return, the <code>yield</code> function
passed to the iterator will return <code>false</code>, stopping the iterator.</p>
</td>
<td class="code">
<pre class="chroma"><code><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">n</span> <span class="o">&gt;=</span> <span class="mi">10</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">break</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="nx">n</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre>
</td>
</tr>
@@ -204,7 +263,13 @@ all its values into a slice.</p>
<pre class="chroma"><code><span class="line"><span class="cl"><span class="go">10
</span></span></span><span class="line"><span class="cl"><span class="go">13
</span></span></span><span class="line"><span class="cl"><span class="go">23
</span></span></span><span class="line"><span class="cl"><span class="go">all: [10 13 23]</span></span></span></code></pre>
</span></span></span><span class="line"><span class="cl"><span class="go">all: [10 13 23]
</span></span></span><span class="line"><span class="cl"><span class="go">1
</span></span></span><span class="line"><span class="cl"><span class="go">1
</span></span></span><span class="line"><span class="cl"><span class="go">2
</span></span></span><span class="line"><span class="cl"><span class="go">3
</span></span></span><span class="line"><span class="cl"><span class="go">5
</span></span></span><span class="line"><span class="cl"><span class="go">8</span></span></span></code></pre>
</td>
</tr>
@@ -223,7 +288,7 @@ all its values into a slice.</p>
</div>
<script>
var codeLines = [];
codeLines.push('');codeLines.push('package main\u000A');codeLines.push('import (\u000A \"fmt\"\u000A \"iter\"\u000A \"slices\"\u000A)\u000A');codeLines.push('type List[T any] struct {\u000A head, tail *element[T]\u000A}\u000A');codeLines.push('type element[T any] struct {\u000A next *element[T]\u000A val T\u000A}\u000A');codeLines.push('func (lst *List[T]) Push(v T) {\u000A if lst.tail \u003D\u003D nil {\u000A lst.head \u003D \u0026element[T]{val: v}\u000A lst.tail \u003D lst.head\u000A } else {\u000A lst.tail.next \u003D \u0026element[T]{val: v}\u000A lst.tail \u003D lst.tail.next\u000A }\u000A}\u000A');codeLines.push('func (lst *List[T]) All() iter.Seq[T] {\u000A return func(yield func(T) bool) {\u000A');codeLines.push(' for e :\u003D lst.head; e !\u003D nil; e \u003D e.next {\u000A if !yield(e.val) {\u000A return\u000A }\u000A }\u000A }\u000A}\u000A');codeLines.push('func main() {\u000A lst :\u003D List[int]{}\u000A lst.Push(10)\u000A lst.Push(13)\u000A lst.Push(23)\u000A');codeLines.push(' for e :\u003D range lst.All() {\u000A fmt.Println(e)\u000A }\u000A');codeLines.push(' all :\u003D slices.Collect(lst.All())\u000A fmt.Println(\"all:\", all)\u000A}\u000A');codeLines.push('');
codeLines.push('');codeLines.push('package main\u000A');codeLines.push('import (\u000A \"fmt\"\u000A \"iter\"\u000A \"slices\"\u000A)\u000A');codeLines.push('type List[T any] struct {\u000A head, tail *element[T]\u000A}\u000A');codeLines.push('type element[T any] struct {\u000A next *element[T]\u000A val T\u000A}\u000A');codeLines.push('func (lst *List[T]) Push(v T) {\u000A if lst.tail \u003D\u003D nil {\u000A lst.head \u003D \u0026element[T]{val: v}\u000A lst.tail \u003D lst.head\u000A } else {\u000A lst.tail.next \u003D \u0026element[T]{val: v}\u000A lst.tail \u003D lst.tail.next\u000A }\u000A}\u000A');codeLines.push('func (lst *List[T]) All() iter.Seq[T] {\u000A return func(yield func(T) bool) {\u000A');codeLines.push(' for e :\u003D lst.head; e !\u003D nil; e \u003D e.next {\u000A if !yield(e.val) {\u000A return\u000A }\u000A }\u000A }\u000A}\u000A');codeLines.push('func genFib() iter.Seq[int] {\u000A return func(yield func(int) bool) {\u000A a, b :\u003D 1, 1\u000A');codeLines.push(' for {\u000A if !yield(a) {\u000A return\u000A }\u000A a, b \u003D b, a+b\u000A }\u000A }\u000A}\u000A');codeLines.push('func main() {\u000A lst :\u003D List[int]{}\u000A lst.Push(10)\u000A lst.Push(13)\u000A lst.Push(23)\u000A');codeLines.push(' for e :\u003D range lst.All() {\u000A fmt.Println(e)\u000A }\u000A');codeLines.push(' all :\u003D slices.Collect(lst.All())\u000A fmt.Println(\"all:\", all)\u000A');codeLines.push(' for n :\u003D range genFib() {\u000A');codeLines.push(' if n \u003E\u003D 10 {\u000A break\u000A }\u000A fmt.Println(n)\u000A }\u000A}\u000A');codeLines.push('');
</script>
<script src="site.js" async></script>
</body>