Dart: Iterable<E> vs. List<E>, always use Iterable?
You should declare your variables as the most precise type that provides the functionality and guarantees that you need.
List guarantees efficient length and random access operations, and gives access to functionality like sort
and shuffle
which are only efficient when they have access to all the elements from the start. They belong on List
because if they had been on Iterable
, every efficient implementation would start by doing toList
to get a list anyway.
You should think the same way about your code: If you want or expect a list, type it as List
. If you can do with any collection, use Iterable
- which usually means that the operations you use can all be implemented by a for-in
over the elements.
If you are always going to transform an iterable into a list before you use it, you might as well type the variable as List
to make sure you remember to make the list.
Or, in short, if you don't care whether it's actually a Set
or Queue
or LinkedList
or whether it's unmodifiable or lazy, you can make it an Iterable
.
(You should still generally only iterate an iterable once - the moment you want to use it twice, it's likely that you'd be better off creating a guaranteed non-lazy collection from it - and List
is the cheapest collection to create).
A List is an indexable collection of objects with a length.
List<E> class
An iterable is a collection of values, or "elements", that can be accessed sequentially.
Iterable<E> class
The elements of the iterable are accessed by getting an Iterator
Iterator<E> class
Now, as you can see iterable does not have any add method. This is on purpose. We get following benefits from using iterable :
- Using iterator we get a safer access to the list. Prevents accidental overriding of list as we get access to only one item at a time
- Allows to keep the logic of modifying the list inside the class that contains it. Others can safely consume it.
- This forces us to keep all complex operations related to the list inside its defining class
Note : The Iterable and Iterator classes support for-in loops. Extend (if possible) or implement Iterable whenever you create a class that can provide Iterators for use in for-in loops. Implement Iterator to define the actual iteration ability.
A List
is completely concrete at its inception. An Iterable
is a "lazy list", and might even be an infinite list. Iterables are computed as needed. They have similar properties, but different realizations.