Language: operators to replace "== null" and "!= null"

Created on 23 Jan 2019  路  18Comments  路  Source: dart-lang/language

Dart already provides the beloved and very useful NULL-aware operators ??, ??= and ?.

I'd really like to see operators to replace the tedious "== null" and "!= null" comparisons.

Something along the lines of:

if (??nullableObject) callFoo();
if (!?nullableObject) callFoo();

Most helpful comment

A simpler solution might be to treat null as falsey like most other languages do.

Please don't do that, I catch all kinds of bugs via our current "it must be a boolean" rule.

All 18 comments

I'm a little afraid of having too many meanings of the same operator.

Also, it's not clear to me which one is == null and which is != null, so the syntax is not self-explanatory.

(Maybe it will be less important to do this checking if we had non-nullable types).

Personally, I don't think these operators are very useful outside of if conditions, ||, &&, and !. A simpler solution might be to treat null as falsey like most other languages do.

A simpler solution might be to treat null as falsey like most other languages do.

Please don't do that, I catch all kinds of bugs via our current "it must be a boolean" rule.

True, but non-nullable types will likely catch most of those statically.

You can actually write the first line with the current null-aware operator: nullableObject ?? callFoo();
The second line would be covered by #131.

132 would allow you to execute more than one expression after the null check.

@munificent I use a _lot_ of nullable types (that is, types that I want "null" to be valid for).

You can actually write the first line with the current null-aware operator: nullableObject ?? callFoo();
@pschiffmann actually, would it make sense to extend the ternary operator to something like: a ?? x : y

What would be absolutely amazing is a hybrid of ?: and ??
object.property ?? currency.format(object.property) : 'N/A'
Or even
object.property ?? currency.format($) : 'N/A'

We probably can't use e1 ?? e2 : e3 because it would be ambiguous. The expression {e1 ?? e2 : e3} is already a map literal {(e1 ?? e2) : e3}, but would also be parsable as a set literal {(e1 ?? e2 : e3)}. I'm also sure it will make parsing harder for the conditional operator ?/: because e1 ? e2 ?? e3 : e4 would prefer to match e4 to e2 ?? e3. In this case, it mustn't, but for e1 ? e2 ?? e3 : e4 : e5 it should. That means that the parsing requires look-ahead to see if there is a later :.

All in all, probably not a viable syntax.

All in all, probably not a viable syntax.

I don't mind the exact syntax - the functionality is what matters

Introduce at least something for Map, so we can simplify JSON parsing from parentMap != null ? parentMap['href'] : defaultValue to something like parentMap?['href'] || defaultValue or similar.

The current plan is to allow parentMap?.['href'] ?? defaultValue. The feature is planned as part of the non-nullable type feature.

What if I want to check a function variable is not null, then call it?

Normally I would write:

if (foo.bar != null) {
    foo.bar();
}

But I would like to write like:

foo.bar?()

This is very useful when using optional callbacks in Flutter.

What if I want to check a function variable is not null, then call it?

We have discussed supporting .?() for that case:

foo.bar?.();

I'm not sure if that made it into the NNBD proposal or not. If not, it's a reasonable change we could add later.

@leafpetersen

This didn't make it into the initial proposal. I think it's likely something we'll follow up with at some point.

Couldn't wait for it =)

For the call-if-not-null case you can use an existing mechanism, the call method:

class A {
  void Function() bar() => null;
}

main() {
  var foo = A();

  // Rather than this: ..
  if (foo.bar != null) foo.bar();
  // .. you could use this:
  foo.bar?.call();
}

This works because invocation of a function f in general may be expressed as f(...) or as f.call(...). It's more concise than the if, but also more robust: It might be a bug to evaluate foo.bar twice because of side-effects.

Good to know! Thank you!

Was this page helpful?
0 / 5 - 0 ratings