Fluttering Dart: Null Safety

Dart’s upcoming superpower

A splash of coffee.
Photo by Ohmky on Unsplash

What is it?

Null safety is the guarantee within an object-oriented programming language that the object references will never have null values.

That translates into 0 "chances" of getting a null reference error. So no more unexpected application crashes caused by this "billion-dollar mistake", as Tony Hoare called the invention of the null pointer.

Currently, JetBrain’s Kotlin and Apple’s Swift are the ones of the most popular programming languages that use null-safe types by default. Soon, Google’s Dart will join the select club.

How will it work?

The types in our code will be considered non-nullable by default. This means that values can’t be null unless specifically marked by us as nullable.

With this, our runtime null-dereference errors turn into edit-time analysis errors and the Dart analyzer can enforce some good practices. For example, it can make sure we check for null before reading a nullable variable.

Also, the Dart compilers and runtimes can optimize away internal null checks, so apps can be faster and smaller.

When will it happen?

Most probably in early 2021, in the 2.12 release of Dart.

The previous releases already introduced a number of breaking changes that prepare this upcoming language feature.

It can be tested right now with a DartPad version that uses the 2.12 dev release, or in your environment if you switch to using that Dart release yourself.

Null safety is still in beta, so don’t use null safety in production code.

After the production release, it will take some time to migrate all packages and code to be null safe compliant. The best guess is that until the release of Dart 3.0 running in mixed mode will still be allowed.

Currently, using the master channel of Flutter to run your app, you’ll get a Running with unsound null safety warning.

Running with unsound null safety
For more information see https://dart.dev/null-safety/unsound-null-safety

That means that the app is running using mixed libraries (just some of them are null safe). Although this is allowed to happen for backwards compatibility reasons, it means that you won’t benefit of the advantages of null safety until you get your app 100% null safe.

Pretty soon, to run or release your app you’ll have to do it with an explicit --no-sound-null-safety paramter.

The devil is in the detail

This new language feature will introduce two new operators: ? and ! , and one new keyword: late.

// In null-safe Dart, none of these can ever be null.String name = getCatName();
final cat = Cat(name);

The ? operator informs Dart that a variable is nullable.

// Let's say we want our cat name to be null// For that, we add ? after the String type
String? name = getCatName();
// Use ?. instead of . with a nullable variable
// Note: the Cat constructor should allow a nullable name
final cat = Cat(name);

The ! operator informs Dart that a nullable expression is no longer null.

// Let's say the Cat constructor doesn't allow a nullable name// We have to make sure that the name is not null
String? name = getCatName() ?? 'Simba';
// Then we tell Dart that we are sure the name is not null
// To do that, we add ! after the variable name
final cat = Cat(name!);

The late keyword allows us to initialize a non-nullable variable at a later moment and if this variable holds the result of an expression, will delay the calculation until its first use.

// name is a late non-nullable String instance member
// Dart will allow it to be null until a Cat is created
class Cat {
late String name;

Cat() {
name = getCatName();

For Lists and Maps, the new operators and keyword apply and work as expected (on the object itself and/or the items it holds within).

// Lists
List<String> listNotNullItemNotNull = [];
List<String>? listNullItemNotNull;
List<String?> listNotNullItemNull = [];
List<String?>? listNullItemNull;
// Maps
Map<String, dynamic> mapNotNullvalueNotNull = {};
Map<String, dynamic>? mapNullvalueNotNull;
Map<String, dynamic?> mapNotNullvalueNull = {};
Map<String, dynamic?>? mapNullvalueNull;

If these can’t be null it doesn’t mean that these can’t be empty. Also, even when all the values in a map are non-null, when we use an invalid key to do a map lookup, the returned value is null.

Sound null safety is coming to the Dart language pretty soon, and as Flutter & Dart developers we must educate ourselves with this new and exciting feature.

Here is an official guide for migrating to null safety.

I, for one, don’t expect it to be very difficult to adapt, adopt, and use this in my past, current, and future projects.

Tha(nk|t’)s all!

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store