Nullsafety demystified and its operators
By: Kefeh Collins
Tags: Flutter, Sound Null Safety, Null Safety, Dart

In order to ensure null safety in all areas of the code, we don’t just have to limit our concern to variables, what about functions (as a matter of fact, functions are variables as well, that hold the value of its return type), so if the return type is non-nullable, it only makes sense to ensure that it never, therefore, returns a null type. So when defining the return type, you take into consideration all the rules already mentioned for the variables above.

Is a valid non null returning function

If a function can only return a null, use void return instead (nothing changes from the previous use)

Also for a function that can return either null or a type, use the “?” operator.

For advanced concepts, some functions are not meant to return anything (explicitly) but are meant to never explicitly finish executing, for example, functions that throw errors etc, it returns the Never, read more here. unreachable code

Handling the return type for every function is just the first step, null can be introduced into a function through its parameters. Let’s start with optional parameters, as the first point for introducing the null, optional parameters like every parameter always have a default value and when none is provided, it defaults to null (before null safety).

And this was perfectly okay. But now with null safety, you must provide a default parameter, because dart noticed that it is evident that the optional parameter will introduce null.

You can also decide to go the route of enforcing that you need x to be null if it has not been passed, by adding the “null type union operator” “?” to the type.

That solves the problem of optional parameters.

We have another issue still, with named parameters, named parameters are by default optional parameters, and go through the same problem as the optional parameter, if you don’t explicitly provide the default value, it often defaults to null before null safety, and with null safety, that becomes an error. You can of course handle them as you have with all optional parameters. A new way to enforce that the parameter is required, and enforces that a value must be passed to the parameter. (before null safety we used the required annotation @required and now it has been replaced with the required keyword

You can not then make a call to optionalParam without providing a value for x.

But some people can really be mischievous and decide to pass a null to x, how do we handle this? We don’t need to, dart automatically points this out, remember, null is not a sub-type of int any longer so it’s not an acceptable argument, it’s more like trying to pass a String to the integer x, which doesn’t make sense right? Perfect.

Let’s look at the point where null manages to enter the function or the control flow. If for example, you have in your function variable you have explicitly stated that they can be null like.

As we saw before, the main errors we had before null safety was that operations and methods defined for the underlying type were not defined for null and when trying to access them on a null value raises an error

Raises an error in nullsafety because y can be null

Let me introduce you to two very useful operators, that help us handle nullable values.

The null aware operator (“?”) which appears after a variable and directly before the operator ex “?.”, “?[]”, “?..” etc

So to make the above work properly

This just means, if y is not null, return the length and if y is null, just default to null regardless.

This just means return the letter at index 0 if y is not null and null otherwise and return the boolean evaluation of the ends with if y is not null and null otherwise respectively.

We have the “value aware operator” “!”, which appears after the variable to validate that the variable is sure to never be null at that instance.

So looking at the examples above, if we know y will not be null, we can then replace “?” with “!” to enforce that y is of the specified type, no need to check for null, proceed with the operation.

The “value aware operator” “!” is very useful when short-circuiting is not an option.

This raises an error, and short-circuiting x to null will not make sense because null can still not be added to 1, so for the x + 1 to be valid, x must be an integer. So… we should only do the operation when we are sure that x is a value of type int hence

Perfect. This wraps our exploratory journey and I hope it has been a good one.

I hope this helps be an introductory and not all exhaustive introduction to null safety. If you need to know more about what’s possible, please don’t hesitate to read more.

Hope to see you in the next one.