Skip to content
DeveloperMemos

Generators in Dart: Creating Streams and Iterables

Dart, Generators, Streams, Iterables1 min read

Generators are a powerful feature of Dart that allow programmers to create streams and iterables dynamically. They are essentially functions that can be paused and resumed on demand to generate a sequence of values. In this article, we will explore how to create generators in Dart and use them to create streams and iterables.

Generators and Iterable

A generator function is declared using the sync* keyword followed by the function signature. The body of the function implements the generator logic using the yield keyword to emit a value. Here's an example:

1Iterable<int> countDownFrom(int n) sync* {
2 while (n > 0) {
3 yield n;
4 n--;
5 }
6}

The countDownFrom function generates an iterable of integers from n down to 1. It uses a while loop to repeatedly yield the next value in the sequence until there are no more values left to generate.

To use the countDownFrom generator, we simply call it like any other function and iterate over the returned iterable:

1void main() {
2 final countdown = countDownFrom(5);
3 for (final number in countdown) {
4 print(number);
5 }
6}

This will output:

15
24
33
42
51

Note that the Iterable object returned by the countDownFrom function is lazy-evaluated. This means that the values are not generated until they are requested by the iterator.

Generators and Stream

Like iterables, generators can also be used to create streams in Dart. A stream is a sequence of asynchronous events where each event is represented by a value. To create a stream using a generator, we use the async* keyword instead of sync*.

Here's an example:

1Stream<int> randomNumbers() async* {
2 final random = Random();
3 while (true) {
4 yield random.nextInt(100);
5 await Future.delayed(Duration(seconds: 1));
6 }
7}

The randomNumbers function generates an infinite stream of random integers between 0 and 99 with a delay of one second between each value. It uses a while loop to repeatedly yield the next value in the sequence and an await expression to pause execution for a duration before generating the next value.

To use the randomNumbers stream, we can listen to it using the listen method:

1import 'dart:async';
2import 'dart:math';
3
4void main() {
5 final randomStream = randomNumbers();
6 final subscription = randomStream.listen((number) {
7 print(number);
8 });
9}

This will output an infinite sequence of random numbers every second.

In Closing

Generators are a powerful feature of Dart that can simplify the code required to generate sequences of values. They can be used in a variety of scenarios, including generating data for UI components, performing background computations, and handling asynchronous events.