What is the Dart null checking idiom or best practice?

There are now 4 null aware operators

??     provides a default if the subject is null

return subject ?? "defaultIfNull";

??=     sets the subject to a default only if the subject is null

This is similar to ?? but sets the subject variable to a default if it is null.

subject ??= "defaultIfNull";

?.     avoid an exception, return null or don't execute function/method if the object on the left is null

object?.x will return null if object is null, object.x would cause an exception if object were null

This can also be used when calling methods. For example

for void methods, object?.myVoidMethod() - if object is null then myVoidMethod will not execute.

and for methods that return values object?.returnValueMethod() - if object is null then returnValueMethod will a return null.

It can also be used with function calls too with the call operator. For example myCallbackFunction?.call() will only execute if myFunction is not null.

...?     from a spread collection, avoid a null item in the final list if the subject list is null

the result of the following

[
  ...[1, 2],
  null,
]

is [1, 2, null]

to avoid the null value use ...?

var resultingList = [
  ...[1, 2],
  ...?subjectList,
];

Posting the following, as I ended up here by searching the title.

As per https://github.com/dart-lang/sdk/issues/66, it seems that the answer to "What is the Dart null checking idiom or best practice?" is:

There is no null checking idiom or best practice in the general case. If null-aware operators don't fit your case use direct comparison as in if (object == null) or if (object != null).


As of Dart 1.12 null-aware operators are available for this type of situation:

bool isConnected(a, b) {
  bool outConn = outgoing[a]?.contains(b) ?? false;
  bool inConn = incoming[a]?.contains(b) ?? false;
  return outConn || inConn;
}

The ?. operator short-circuits to null if the left-hand side is null, and the ?? operator returns the left-hand side if it is not null, and the right-hand side otherwise.

The statement

outgoing[a]?.contains(b)

will thus either evaluate to null if outgoing[a] is null, or the boolean result of contains(b) if it is not.

That means the resulting statement will be one of the following:

bool outConn = null ?? false; // false
bool outConn = false ?? false; // false
bool outConn = true ?? false; // true

The same applies to the inConn boolean, which means both inConn and outConn are guaranteed to be non-null, allowing us to return the result of ||ing the two.

Tags:

Dart