language
language copied to clipboard
Null-aware collection-for
Currently, for collection-for's on nullable collections, we need a null check:
List<int>? myInts = ...;
if (myInts != null) {
for (final i in myInts) {
// use i
}
}
It would be nice if we could have a null-aware version of this syntax, something along the lines of
for(final i in myInts?) ...
or
for(final i in? myInts) ...
which would skip iteration if the iterable were null
.
Sorry if this already exists and I'm just (null-)unaware of it :)
It does not exist. I'm not sure it will.
One issue is that you should rarely have a nullable collection, it's better to use an empty collection, and not have two ways to represent "no elements". Another is that they syntax could be better used for something else.
If we get Null-aware elements (#323), then you should be able to write:
for (final i in [?myInts]) { ... }
and with a little luck and prodding, the compiler should be able to optimize that into:
if (myInts case final myInts?) for (final i in myInts) { ... }
(if you don't want to write that out yourself).
you should rarely have a nullable collection
while largely I agree, one situation I have run into this is optional function parameters.
Also, do you mind explaining or linking to whatever pattern-matching foo is happening here:
if (myInts case final myInts?) ...
, I don't think I've seen that syntax before
@anqit https://dart.dev/language/pattern-types#null-check
It matches if myInts
are not null and it will define a new variable called myInts
inside the scope of the if-statement which have a non-nullable type.
If we get Null-aware elements (#323), then you should be able to write:
for (final i in [?myInts]) { ... }
That wouldn't do what you want because it would only unwrap the outer list, so if myInts
is not null
, then you get one iteration where i
is bound to the entire myInts
list. What you really want is:
for (final i in [...?myInts]) { ... }
That's a little silly, but does work and do the right thing.
Figuring out what sort of null-aware operations are worth adding to Dart and which aren't is hard. In theory, we could support null-aware operations for every possible operation that has a reasonable "do nothing" semantics to fall back on when the value is null
. That's definitely the case for for
loops: just don't execute the body at all. We could also have null-aware while
loops.
But in most cases, I think it's easy enough to use ??
and then you get code that's clearer about what happens when the value is null
.
I think we should guarantee that a spread of a list literal, ...[something in here]
, is always optimized to avoid allocating a list.
It will guaranteed work as an element by having each element emitted by the content of the list being directly emitted into the outer elements instead. (Like yield*
flattening, if we do that.)
I think we should guarantee that a spread of a list literal,
...[something in here]
, is always optimized to avoid allocating a list. It will guaranteed work as an element by having each element emitted by the content of the list being directly emitted into the outer elements instead. (Likeyield*
flattening, if we do that.)
I like this idea. Anytime I'm writing an if statement in a List (like I do a lot in Flutter) I always get worried about using the spread operator like so:
return Column(
children: [
if (condition) ...[
FooWidget(),
const SizedBox(height: 10),
],
],
);
Don't mean to hijack this issue, just saw Irhn's comment and wanted to reply to it