Initial example of range over custom types
This commit is contained in:
@@ -22,6 +22,7 @@ Interfaces
|
||||
Enums
|
||||
Struct Embedding
|
||||
Generics
|
||||
Range over Custom Types
|
||||
Errors
|
||||
Custom Errors
|
||||
Goroutines
|
||||
|
@@ -1,2 +1,2 @@
|
||||
d6b4792fc509f0dcd84f15ed92097f52a73eb877
|
||||
MNfKskDAZ6d
|
||||
1ad71763360077271687c5e9d147c89c0b580b0a
|
||||
7v7vElzhAeO
|
||||
|
72
examples/range-over-custom-types/range-over-custom-types.go
Normal file
72
examples/range-over-custom-types/range-over-custom-types.go
Normal file
@@ -0,0 +1,72 @@
|
||||
// Starting with version 1.23, Go has added support for
|
||||
// [iterators](https://go.dev/blog/range-functions),
|
||||
// which lets us range over custom types.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"iter"
|
||||
"slices"
|
||||
)
|
||||
|
||||
// Let's look at the `List` type from the
|
||||
// [previous example](generics) again. In that example
|
||||
// we had an `AllElements` method that returned a slice
|
||||
// of all elements in the list. With Go iterators, we
|
||||
// can do it better - as shown below.
|
||||
type List[T any] struct {
|
||||
head, tail *element[T]
|
||||
}
|
||||
|
||||
type element[T any] struct {
|
||||
next *element[T]
|
||||
val T
|
||||
}
|
||||
|
||||
func (lst *List[T]) Push(v T) {
|
||||
if lst.tail == nil {
|
||||
lst.head = &element[T]{val: v}
|
||||
lst.tail = lst.head
|
||||
} else {
|
||||
lst.tail.next = &element[T]{val: v}
|
||||
lst.tail = lst.tail.next
|
||||
}
|
||||
}
|
||||
|
||||
// All returns an _iterator_, which in Go is a function
|
||||
// with a special signature.
|
||||
func (lst *List[T]) All() iter.Seq[T] {
|
||||
return func(yield func(T) bool) {
|
||||
// The iterator function takes another function as
|
||||
// a parameter, called `yield` by convention (but
|
||||
// the name can be arbitrary). It will call `yield` for
|
||||
// every element we want to iterate over, and note `yield`'s
|
||||
// return value for a potential early termination.
|
||||
for e := lst.head; e != nil; e = e.next {
|
||||
if !yield(e.val) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
lst := List[int]{}
|
||||
lst.Push(10)
|
||||
lst.Push(13)
|
||||
lst.Push(23)
|
||||
|
||||
// Since `List.All` returns an interator, it can be used
|
||||
// in a regular `range` loop!
|
||||
for e := range lst.All() {
|
||||
fmt.Println(e)
|
||||
}
|
||||
|
||||
// Packages like [slices](https://pkg.go.dev/slices) have
|
||||
// a number of useful functions to work with iterators.
|
||||
// For example, `Collect` takes any iterator and collects
|
||||
// all its values into a slice.
|
||||
all := slices.Collect(lst.All())
|
||||
fmt.Println("all:", all)
|
||||
}
|
@@ -0,0 +1,2 @@
|
||||
28edd55763e81476f37e68085f5f79555c15ffe8
|
||||
Dc3AddmC8Jc
|
@@ -0,0 +1,5 @@
|
||||
10
|
||||
13
|
||||
23
|
||||
all: [10 13 23]
|
||||
|
2
go.mod
2
go.mod
@@ -1,6 +1,6 @@
|
||||
module github.com/mmcgrana/gobyexample
|
||||
|
||||
go 1.22.0
|
||||
go 1.23.0
|
||||
|
||||
require (
|
||||
github.com/alecthomas/chroma/v2 v2.10.0
|
||||
|
2
public/errors
generated
2
public/errors
generated
@@ -12,7 +12,7 @@
|
||||
}
|
||||
|
||||
if (e.key == "ArrowLeft") {
|
||||
window.location.href = 'generics';
|
||||
window.location.href = 'range-over-custom-types';
|
||||
}
|
||||
|
||||
|
||||
|
39
public/generics
generated
39
public/generics
generated
@@ -17,7 +17,7 @@
|
||||
|
||||
|
||||
if (e.key == "ArrowRight") {
|
||||
window.location.href = 'errors';
|
||||
window.location.href = 'range-over-custom-types';
|
||||
}
|
||||
|
||||
}
|
||||
@@ -45,7 +45,7 @@
|
||||
|
||||
</td>
|
||||
<td class="code leading">
|
||||
<a href="https://go.dev/play/p/MNfKskDAZ6d"><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/7v7vElzhAeO"><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>
|
||||
@@ -136,11 +136,14 @@ parameters in place. The type is <code>List[T]</code>, not <code>List</code>.</p
|
||||
|
||||
<tr>
|
||||
<td class="docs">
|
||||
|
||||
<p>AllElements returns all the List elements as a slice.
|
||||
In the next example we’ll see a more idiomatic way
|
||||
of iterating over all elements of custom types.</p>
|
||||
|
||||
</td>
|
||||
<td class="code leading">
|
||||
|
||||
<pre class="chroma"><code><span class="line"><span class="cl"><span class="kd">func</span> <span class="p">(</span><span class="nx">lst</span> <span class="o">*</span><span class="nx">List</span><span class="p">[</span><span class="nx">T</span><span class="p">])</span> <span class="nf">GetAll</span><span class="p">()</span> <span class="p">[]</span><span class="nx">T</span> <span class="p">{</span>
|
||||
<pre class="chroma"><code><span class="line"><span class="cl"><span class="kd">func</span> <span class="p">(</span><span class="nx">lst</span> <span class="o">*</span><span class="nx">List</span><span class="p">[</span><span class="nx">T</span><span class="p">])</span> <span class="nf">AllElements</span><span class="p">()</span> <span class="p">[]</span><span class="nx">T</span> <span class="p">{</span>
|
||||
</span></span><span class="line"><span class="cl"> <span class="kd">var</span> <span class="nx">elems</span> <span class="p">[]</span><span class="nx">T</span>
|
||||
</span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="nx">e</span> <span class="o">:=</span> <span class="nx">lst</span><span class="p">.</span><span class="nx">head</span><span class="p">;</span> <span class="nx">e</span> <span class="o">!=</span> <span class="kc">nil</span><span class="p">;</span> <span class="nx">e</span> <span class="p">=</span> <span class="nx">e</span><span class="p">.</span><span class="nx">next</span> <span class="p">{</span>
|
||||
</span></span><span class="line"><span class="cl"> <span class="nx">elems</span> <span class="p">=</span> <span class="nb">append</span><span class="p">(</span><span class="nx">elems</span><span class="p">,</span> <span class="nx">e</span><span class="p">.</span><span class="nx">val</span><span class="p">)</span>
|
||||
@@ -172,7 +175,7 @@ automatically.</p>
|
||||
</td>
|
||||
<td class="code leading">
|
||||
|
||||
<pre class="chroma"><code><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">"index of foo:"</span><span class="p">,</span> <span class="nf">SlicesIndex</span><span class="p">(</span><span class="nx">s</span><span class="p">,</span> <span class="s">"foo"</span><span class="p">))</span></span></span></code></pre>
|
||||
<pre class="chroma"><code><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">"index of zoo:"</span><span class="p">,</span> <span class="nf">SlicesIndex</span><span class="p">(</span><span class="nx">s</span><span class="p">,</span> <span class="s">"zoo"</span><span class="p">))</span></span></span></code></pre>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -183,8 +186,7 @@ automatically.</p>
|
||||
</td>
|
||||
<td class="code leading">
|
||||
|
||||
<pre class="chroma"><code><span class="line"><span class="cl"> <span class="c1">//_ = MapKeys[int, string](m)
|
||||
</span></span></span></code></pre>
|
||||
<pre class="chroma"><code><span class="line"><span class="cl"> <span class="nx">_</span> <span class="p">=</span> <span class="nx">SlicesIndex</span><span class="p">[[]</span><span class="kt">string</span><span class="p">,</span> <span class="kt">string</span><span class="p">](</span><span class="nx">s</span><span class="p">,</span> <span class="s">"zoo"</span><span class="p">)</span></span></span></code></pre>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -198,7 +200,7 @@ automatically.</p>
|
||||
</span></span><span class="line"><span class="cl"> <span class="nx">lst</span><span class="p">.</span><span class="nf">Push</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span>
|
||||
</span></span><span class="line"><span class="cl"> <span class="nx">lst</span><span class="p">.</span><span class="nf">Push</span><span class="p">(</span><span class="mi">13</span><span class="p">)</span>
|
||||
</span></span><span class="line"><span class="cl"> <span class="nx">lst</span><span class="p">.</span><span class="nf">Push</span><span class="p">(</span><span class="mi">23</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">"list:"</span><span class="p">,</span> <span class="nx">lst</span><span class="p">.</span><span class="nf">GetAll</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">"list:"</span><span class="p">,</span> <span class="nx">lst</span><span class="p">.</span><span class="nf">AllElements</span><span class="p">())</span>
|
||||
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -211,32 +213,19 @@ automatically.</p>
|
||||
<td class="docs">
|
||||
|
||||
</td>
|
||||
<td class="code leading">
|
||||
<td class="code">
|
||||
|
||||
<pre class="chroma"><code><span class="line"><span class="cl"><span class="gp">$</span> go run generics.go
|
||||
</span></span><span class="line"><span class="cl"><span class="go">keys: [4 1 2]
|
||||
</span></span><span class="line"><span class="cl"><span class="go">index of zoo: 2
|
||||
</span></span></span><span class="line"><span class="cl"><span class="go">list: [10 13 23]</span></span></span></code></pre>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="docs">
|
||||
<p>Note: The order of iteration over map keys is not
|
||||
defined in Go, so different invocations may
|
||||
result in different orders.</p>
|
||||
|
||||
</td>
|
||||
<td class="code empty">
|
||||
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
|
||||
<p class="next">
|
||||
Next example: <a href="errors">Errors</a>.
|
||||
Next example: <a href="range-over-custom-types">Range over Custom Types</a>.
|
||||
</p>
|
||||
|
||||
|
||||
@@ -247,7 +236,7 @@ result in different orders.</p>
|
||||
</div>
|
||||
<script>
|
||||
var codeLines = [];
|
||||
codeLines.push('');codeLines.push('package main\u000A');codeLines.push('import \"fmt\"\u000A');codeLines.push('func SlicesIndex[S ~[]E, E comparable](s S, v E) int {\u000A for i :\u003D range s {\u000A if v \u003D\u003D s[i] {\u000A return i\u000A }\u000A }\u000A return -1\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]) GetAll() []T {\u000A var elems []T\u000A for e :\u003D lst.head; e !\u003D nil; e \u003D e.next {\u000A elems \u003D append(elems, e.val)\u000A }\u000A return elems\u000A}\u000A');codeLines.push('func main() {\u000A var s \u003D []string{\"foo\", \"bar\", \"zoo\"}\u000A');codeLines.push(' fmt.Println(\"index of foo:\", SlicesIndex(s, \"foo\"))\u000A');codeLines.push(' //_ \u003D MapKeys[int, string](m)\u000A');codeLines.push(' lst :\u003D List[int]{}\u000A lst.Push(10)\u000A lst.Push(13)\u000A lst.Push(23)\u000A fmt.Println(\"list:\", lst.GetAll())\u000A}\u000A');codeLines.push('');codeLines.push('');
|
||||
codeLines.push('');codeLines.push('package main\u000A');codeLines.push('import \"fmt\"\u000A');codeLines.push('func SlicesIndex[S ~[]E, E comparable](s S, v E) int {\u000A for i :\u003D range s {\u000A if v \u003D\u003D s[i] {\u000A return i\u000A }\u000A }\u000A return -1\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]) AllElements() []T {\u000A var elems []T\u000A for e :\u003D lst.head; e !\u003D nil; e \u003D e.next {\u000A elems \u003D append(elems, e.val)\u000A }\u000A return elems\u000A}\u000A');codeLines.push('func main() {\u000A var s \u003D []string{\"foo\", \"bar\", \"zoo\"}\u000A');codeLines.push(' fmt.Println(\"index of zoo:\", SlicesIndex(s, \"zoo\"))\u000A');codeLines.push(' _ \u003D SlicesIndex[[]string, string](s, \"zoo\")\u000A');codeLines.push(' lst :\u003D List[int]{}\u000A lst.Push(10)\u000A lst.Push(13)\u000A lst.Push(23)\u000A fmt.Println(\"list:\", lst.AllElements())\u000A}\u000A');codeLines.push('');
|
||||
</script>
|
||||
<script src="site.js" async></script>
|
||||
</body>
|
||||
|
2
public/index.html
generated
2
public/index.html
generated
@@ -81,6 +81,8 @@
|
||||
|
||||
<li><a href="generics">Generics</a></li>
|
||||
|
||||
<li><a href="range-over-custom-types">Range over Custom Types</a></li>
|
||||
|
||||
<li><a href="errors">Errors</a></li>
|
||||
|
||||
<li><a href="custom-errors">Custom Errors</a></li>
|
||||
|
230
public/range-over-custom-types
generated
Normal file
230
public/range-over-custom-types
generated
Normal file
@@ -0,0 +1,230 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Go by Example: Range over Custom Types</title>
|
||||
<link rel=stylesheet href="site.css">
|
||||
</head>
|
||||
<script>
|
||||
window.onkeydown = (e) => {
|
||||
if (e.ctrlKey || e.altKey || e.shiftKey) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (e.key == "ArrowLeft") {
|
||||
window.location.href = 'generics';
|
||||
}
|
||||
|
||||
|
||||
if (e.key == "ArrowRight") {
|
||||
window.location.href = 'errors';
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
<body>
|
||||
<div class="example" id="range-over-custom-types">
|
||||
<h2><a href="./">Go by Example</a>: Range over Custom Types</h2>
|
||||
|
||||
<table>
|
||||
|
||||
<tr>
|
||||
<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>
|
||||
|
||||
</td>
|
||||
<td class="code empty leading">
|
||||
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="docs">
|
||||
|
||||
</td>
|
||||
<td class="code leading">
|
||||
<a href="https://go.dev/play/p/Dc3AddmC8Jc"><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>
|
||||
|
||||
<tr>
|
||||
<td class="docs">
|
||||
|
||||
</td>
|
||||
<td class="code leading">
|
||||
|
||||
<pre class="chroma"><code><span class="line"><span class="cl"><span class="kn">import</span> <span class="p">(</span>
|
||||
</span></span><span class="line"><span class="cl"> <span class="s">"fmt"</span>
|
||||
</span></span><span class="line"><span class="cl"> <span class="s">"iter"</span>
|
||||
</span></span><span class="line"><span class="cl"> <span class="s">"slices"</span>
|
||||
</span></span><span class="line"><span class="cl"><span class="p">)</span></span></span></code></pre>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="docs">
|
||||
<p>Let’s look at the <code>List</code> type from the
|
||||
<a href="generics">previous example</a> again. In that example
|
||||
we had an <code>AllElements</code> method that returned a slice
|
||||
of all elements in the list. With Go iterators, we
|
||||
can do it better - as shown below.</p>
|
||||
|
||||
</td>
|
||||
<td class="code leading">
|
||||
|
||||
<pre class="chroma"><code><span class="line"><span class="cl"><span class="kd">type</span> <span class="nx">List</span><span class="p">[</span><span class="nx">T</span> <span class="nx">any</span><span class="p">]</span> <span class="kd">struct</span> <span class="p">{</span>
|
||||
</span></span><span class="line"><span class="cl"> <span class="nx">head</span><span class="p">,</span> <span class="nx">tail</span> <span class="o">*</span><span class="nx">element</span><span class="p">[</span><span class="nx">T</span><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">
|
||||
|
||||
</td>
|
||||
<td class="code leading">
|
||||
|
||||
<pre class="chroma"><code><span class="line"><span class="cl"><span class="kd">type</span> <span class="nx">element</span><span class="p">[</span><span class="nx">T</span> <span class="nx">any</span><span class="p">]</span> <span class="kd">struct</span> <span class="p">{</span>
|
||||
</span></span><span class="line"><span class="cl"> <span class="nx">next</span> <span class="o">*</span><span class="nx">element</span><span class="p">[</span><span class="nx">T</span><span class="p">]</span>
|
||||
</span></span><span class="line"><span class="cl"> <span class="nx">val</span> <span class="nx">T</span>
|
||||
</span></span><span class="line"><span class="cl"><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="kd">func</span> <span class="p">(</span><span class="nx">lst</span> <span class="o">*</span><span class="nx">List</span><span class="p">[</span><span class="nx">T</span><span class="p">])</span> <span class="nf">Push</span><span class="p">(</span><span class="nx">v</span> <span class="nx">T</span><span class="p">)</span> <span class="p">{</span>
|
||||
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">lst</span><span class="p">.</span><span class="nx">tail</span> <span class="o">==</span> <span class="kc">nil</span> <span class="p">{</span>
|
||||
</span></span><span class="line"><span class="cl"> <span class="nx">lst</span><span class="p">.</span><span class="nx">head</span> <span class="p">=</span> <span class="o">&</span><span class="nx">element</span><span class="p">[</span><span class="nx">T</span><span class="p">]{</span><span class="nx">val</span><span class="p">:</span> <span class="nx">v</span><span class="p">}</span>
|
||||
</span></span><span class="line"><span class="cl"> <span class="nx">lst</span><span class="p">.</span><span class="nx">tail</span> <span class="p">=</span> <span class="nx">lst</span><span class="p">.</span><span class="nx">head</span>
|
||||
</span></span><span class="line"><span class="cl"> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
|
||||
</span></span><span class="line"><span class="cl"> <span class="nx">lst</span><span class="p">.</span><span class="nx">tail</span><span class="p">.</span><span class="nx">next</span> <span class="p">=</span> <span class="o">&</span><span class="nx">element</span><span class="p">[</span><span class="nx">T</span><span class="p">]{</span><span class="nx">val</span><span class="p">:</span> <span class="nx">v</span><span class="p">}</span>
|
||||
</span></span><span class="line"><span class="cl"> <span class="nx">lst</span><span class="p">.</span><span class="nx">tail</span> <span class="p">=</span> <span class="nx">lst</span><span class="p">.</span><span class="nx">tail</span><span class="p">.</span><span class="nx">next</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">
|
||||
<p>All returns an <em>iterator</em>, which in Go is a function
|
||||
with a special signature.</p>
|
||||
|
||||
</td>
|
||||
<td class="code leading">
|
||||
|
||||
<pre class="chroma"><code><span class="line"><span class="cl"><span class="kd">func</span> <span class="p">(</span><span class="nx">lst</span> <span class="o">*</span><span class="nx">List</span><span class="p">[</span><span class="nx">T</span><span class="p">])</span> <span class="nf">All</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="nx">T</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="nx">T</span><span class="p">)</span> <span class="kt">bool</span><span class="p">)</span> <span class="p">{</span></span></span></code></pre>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="docs">
|
||||
<p>The iterator function takes another function as
|
||||
a parameter, called <code>yield</code> by convention (but
|
||||
the name can be arbitrary). It will call <code>yield</code> for
|
||||
every element we want to iterate over, and note <code>yield</code>’s
|
||||
return value for a potential early termination.</p>
|
||||
|
||||
</td>
|
||||
<td class="code leading">
|
||||
|
||||
<pre class="chroma"><code><span class="line"><span class="cl"> <span class="k">for</span> <span class="nx">e</span> <span class="o">:=</span> <span class="nx">lst</span><span class="p">.</span><span class="nx">head</span><span class="p">;</span> <span class="nx">e</span> <span class="o">!=</span> <span class="kc">nil</span><span class="p">;</span> <span class="nx">e</span> <span class="p">=</span> <span class="nx">e</span><span class="p">.</span><span class="nx">next</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">e</span><span class="p">.</span><span class="nx">val</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="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">
|
||||
|
||||
</td>
|
||||
<td class="code leading">
|
||||
|
||||
<pre class="chroma"><code><span class="line"><span class="cl"><span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
|
||||
</span></span><span class="line"><span class="cl"> <span class="nx">lst</span> <span class="o">:=</span> <span class="nx">List</span><span class="p">[</span><span class="kt">int</span><span class="p">]{}</span>
|
||||
</span></span><span class="line"><span class="cl"> <span class="nx">lst</span><span class="p">.</span><span class="nf">Push</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span>
|
||||
</span></span><span class="line"><span class="cl"> <span class="nx">lst</span><span class="p">.</span><span class="nf">Push</span><span class="p">(</span><span class="mi">13</span><span class="p">)</span>
|
||||
</span></span><span class="line"><span class="cl"> <span class="nx">lst</span><span class="p">.</span><span class="nf">Push</span><span class="p">(</span><span class="mi">23</span><span class="p">)</span></span></span></code></pre>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<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>
|
||||
|
||||
</td>
|
||||
<td class="code leading">
|
||||
|
||||
<pre class="chroma"><code><span class="line"><span class="cl"> <span class="k">for</span> <span class="nx">e</span> <span class="o">:=</span> <span class="k">range</span> <span class="nx">lst</span><span class="p">.</span><span class="nf">All</span><span class="p">()</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="nx">e</span><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">
|
||||
<p>Packages like <a href="https://pkg.go.dev/slices">slices</a> have
|
||||
a number of useful functions to work with iterators.
|
||||
For example, <code>Collect</code> takes any iterator and collects
|
||||
all its values into a slice.</p>
|
||||
|
||||
</td>
|
||||
<td class="code">
|
||||
|
||||
<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">"all:"</span><span class="p">,</span> <span class="nx">all</span><span class="p">)</span>
|
||||
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
<table>
|
||||
|
||||
<tr>
|
||||
<td class="docs">
|
||||
|
||||
</td>
|
||||
<td class="code">
|
||||
|
||||
<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>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
|
||||
<p class="next">
|
||||
Next example: <a href="errors">Errors</a>.
|
||||
</p>
|
||||
|
||||
|
||||
<p class="footer">
|
||||
by <a href="https://markmcgranaghan.com">Mark McGranaghan</a> and <a href="https://eli.thegreenplace.net">Eli Bendersky</a> | <a href="https://github.com/mmcgrana/gobyexample">source</a> | <a href="https://github.com/mmcgrana/gobyexample#license">license</a>
|
||||
</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('');
|
||||
</script>
|
||||
<script src="site.js" async></script>
|
||||
</body>
|
||||
</html>
|
Reference in New Issue
Block a user