Exploring the upcoming Go Generators

Maku
2 min readFeb 27, 2024

--

Go 1.22 just shipped a couple weeks ago and brought us some exciting new changes to the for range loops. One of those changes is currently still experimental, but let’s take a closer look at it either way.

But first off..

What even are generators?

A generator is a function that returns an array of elements, but instead of returning them all at once it only yields one element at a time, for each iteration of the for loop.

Let’s look at a quick python example, since python had generators for a while already.

def sequence():
i = 0
while True:
yield i
i += 1

for number in sequence():
print(number)

# output:
# 0
# 1
# 2
# …

You can see the keyword yield being used to return the current iteration of the sequence, while still maintaining the state of the function, allowing us to create an infinite sequence of numbers.

Okay cool, but why do we need that?

Instead of having to build an array with all values first, a generator can just yield them one at a time, allowing the caller to start processing the values right away. They can also help reduce memory usage in certain cases.

In short, a generator looks like a function but behaves like an iterator.

Anyways, let’s look at how to use them in Go

To enable them, we have to set the following flag

GOEXPERIMENT=rangefunc

With that set, let’s rewrite the the example from earlier into Go.

func Sequence(yield func(int) bool) {
i := 0
for {
if !yield(i) {
return
}
i += 1
}
}

func main() {
for i := range Sequence {
fmt.Println(i)
}
}

And that’s it! 🎉 Unfortunately the syntax isn’t as straightforward as python, our generator Sequence has the yield function as a parameter, which we can then call every time we want to yield a value.

From my understanding, generators are currently limited to only two yielded values, but there might still be some changes for their actual release.

If you want to learn more, check out the Go Wiki: Rangefunc Experiment article and the related Github Issue.

--

--