Basically, you should never use any of those constructors.
Each has its use, but most of those uses can be written using list literals now.
The List.generate
is a pendant to List.filled
. The latter creates a list filled with the same value in each slot, the former allows you to compute a new value for each slot.
With collection-for, I'd probably write:
var newList = [for (var i = 0; i < 10; i++) compute(i)];
instead of
var newList = List.generate(10, compute);
(even more so if I can inline the compute
function).
The one case where generate
makes sense is to create a fixed-length list. The literal cannot do that.
I'd also say that you should never use List.of(something)
.
Use something.toList()
or [...something]
instead. If you need to up-cast, say create a List<num>
from an Iterable<int>
, you can do <num>[...something]
, but you can't use toList
. If you need to make a fixed-length List<num>
, ... then I think List<num>.of(something, growable: false)
is actually the simplest solution.
The only reason to use List.from
is when the original iterable does not have as tight a type as needed. If you know that your Iterable<num>
contains only integers, you might want to do List<int>.from(iterable)
. You can also do iterable.cast<int>().toList()
or [for (var v in iterable) v as int]
, but List.from
can be shorter. Always provide a type variable to List.from
.
So, in general: Only use one of these constructors if you need a fixed-length list (passing growable: false
), or if you want to down-cast the elements using List.from
, and then always provide the type argument.
Otherwise use list literals. That's probably going to be more efficient too because it avoids some function calls.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…