-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial example of range over custom types
- Loading branch information
Showing
10 changed files
with
330 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,6 +22,7 @@ Interfaces | |
Enums | ||
Struct Embedding | ||
Generics | ||
Range over Custom Types | ||
Errors | ||
Custom Errors | ||
Goroutines | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
d6b4792fc509f0dcd84f15ed92097f52a73eb877 | ||
MNfKskDAZ6d | ||
1ad71763360077271687c5e9d147c89c0b580b0a | ||
7v7vElzhAeO |
72 changes: 72 additions & 0 deletions
72
examples/range-over-custom-types/range-over-custom-types.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) | ||
} |
2 changes: 2 additions & 0 deletions
2
examples/range-over-custom-types/range-over-custom-types.hash
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
28edd55763e81476f37e68085f5f79555c15ffe8 | ||
Dc3AddmC8Jc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
10 | ||
13 | ||
23 | ||
all: [10 13 23] | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Oops, something went wrong.