Advanced Dart — Generator, Stream, Extension, Mixins, Generics…

Debanshu Datta
Backyard Programmers
6 min readJun 8, 2022
Photo by Immo Wegmann on Unsplash

I was revisiting, Flutter after some time so, I thought it will be great to put up my understanding with examples and summarise it here. These are some of the topics that people tend to ignore this gives us a wide understanding of the Dart as a language. This is important, let's start with the explanation ✨

1. Extension🔗

It is a simple term, you can think of it as the ability of a programmer to add functions to an existing class. It’s understood with an example.

Suppose you have a class called Dog, you need to add a function train() you can directly add to the class Dog. Now suppose you don’t have the access to the Dog class or you want to segregate the function based on some use-case and based on the use-case you want to import a set of functions. Now you can do that with an extension on the class.

You can see in the example we have added the extension function, the name Train , there is no specific reason to understand the use of the name it is generally used in case you only want to include a specific extension.

2. Async/Await & Future🔮

Before everything, you need to know about an asynchronous computation. It is when a program cannot provide a result immediately when it is started, unlike a synchronous computation which does compute a result immediately by either returning a value or by throwing. An asynchronous computation may need to wait for something external to the program (reading a file, querying a database, fetching a web page) which takes time. Instead of blocking all computation until the result is available, the asynchronous computation immediately returns a Future which will eventually "complete" the result.

To perform an asynchronous computation, you use a async function which always produces a future. Inside such an asynchronous function, you can use the await operation to delay execution until another asynchronous computation has a result. While the execution of the awaiting function is delayed, the program is not blocked and can continue doing other things.

See the below code this will help you to understand it in greater detail.

3. Stream🚝

The stream you can think of as a stream of data is asynchronous however it is continuous. You can think of it as a pipe of data it either completes successfully or never completes or errors out. A stream is a sequence of asynchronous events. It is like an asynchronous Iterable — where, instead of getting the next event when you ask for it, the stream tells you that there is an event when it is ready.

Receiving stream events

Streams can be created in many ways, which is a topic for another article. Still, they can all be used in the same way: the asynchronous for loop (commonly just called await for) iterates over the events of a stream like the for loop iterates over an Iterable. For example:

Future<int> sumStream(Stream<int> stream) async {
var sum = 0;
await for (final value in stream) {
sum += value;
}
return sum;
}

4. Generator✈

Dart Generator is a unique function that allows us to produce a sequence of values. Generators return values on demand; the value is generated when we try to iterate over the iterators. Dart provides built-in support for two types of generator functions.

  • Synchronous Generators
  • Asynchronous Generators
Let's first understand the difference between LIST & ITERABLE. You can think of Iterable as a list of things which is not completely calculated when it begins, it is basically lazy collection. While List in Dart is egar i.e, it is already ready then it is being called.yeild: The yield returns the single value to the sequence at a time but does not stop the execution of the generator function completely. It returns a value for each execution of the generator function.
sync*: The sync* keyword is used to declare the synchronize generator function. It returns the value when we try to iterator the value not when it was created.
async*: The async keyword is used to declare the asynchronous generators. It returns the stream object.

Synchronous Generator

It returns an iterable object which carries value synchronously. The yeild keyword is used along with marking the synchronous generator function body as sync* to generator values.

What is the benefit? You might think why complicating things, suppose each value you yield has heavy computation. You can break out of the while loop any time, and any values after that will not be computed.

Asynchronous Generators

It returns a stream object which carries value asynchronously. The yeild keyword is used along with marking the asynchronous generator function body as async* to generator values.

5. Mixins🛰

In OOPs, we have classes, Interfaces, Abstract Classes, etc. Dart provides one more option of Mixins.

Mixins are a way of reusing a class’s code in multiple class hierarchies.

Mixins allow you to plug in code blocks without needing to create subclasses. Mixins are a very useful way of avoiding code duplication without inheritance. You can see the two vertical images on the left and the right as the outcome with mixins.

6. Generics🚀

In Dart by default, collections are heterogeneous. However, by the use of generics, we can make a collection to hold homogeneous values. The use of Generics makes the use of a single compulsory data type to be held inside the collection. Such collections are called type-safe collections.

Generics are often required for type safety, but they have more benefits than just allowing your code to run:

  • Properly specifying generic types results in better-generated code.
  • You can use generics to reduce code duplication.
var names = <String>[];
names.addAll(['Seth', 'Kathy', 'Lars']);
names.add(42); // Error

For any doubts and suggestions, you can reach out on my Instagram, or LinkedIn. Follow me for Dart & Kotlin content and more. Happy Coding!

I will well appreciate one of these 👏

Recent Post

--

--

Debanshu Datta
Backyard Programmers

Android(L2) @Gojek | Mobile Developer | Backend Developer (Java/Kotlin)