The following produces a compilation error:
String? str = null;
print(str.toUpperCase());
But why is that, I mean isn't using String?
instead of String
means that I can work with the null
value?
CodePudding user response:
The point of static null safety is to avoid runtime errors.
In pre-null-safe Dart, you could write String s = null; print(s.toUpperCase());
and get a runtime error.
In null-safe Dart, you cannot. Because the variable can contain null
, it must be typed as String? s = null;
.
You cannot call toUpperCase
on String?
, aka. "String
or Null
", because Null
doesn't have a toUpperCase
.
You need to promote the value from String?
to String
before you can call String
methods on it. You can do that in many different ways, which can be generalized to two: Those which throw if the value is null
, and those which take a different path (other than throwing) if the value is null
, so you won't call the method on null
. You then have to do something else on the other path.
The most common ways to call methods on a nullable value are:
Throwing ones:
print(s!.toUpperCase());
. Thes!
throws ifs
isnull
, and otherwise it has typeString
, so you can calltoUpperCase
on it. That simulates the pre-null-safety behavior of checking fornull
, and throwing if you find it. The!
here is called the "null check operator".print((as as String).toUpperCase());
. Same ass!
, just with more steps.
Non-throwing:
print(s?.toUpperCase());
. Thes?.toUpperCase()
callstoUpperCase
ons
only ifs
is notnull
. Ifs
isnull
, it doesn't call anything, and the result is againnull
. Luckilyprint
acceptsnull
as an argument, so you can print it. This is called a "null aware method invocation".print(s == null ? null : s.toUpperCase())
, pretty much the same ass?.toUpperCase()
, just with more steps. Relies on promotion, and therefore only works on local variables.if (s != null) print(s.toUpperCase());
. Also relies on promotion, so only works ifs
is a local variable. Always a good choice, just not always the shortest one.if (s is String) print(s.toUpperCase());
. The longer and slower way to do the same thing as!= null
.
Or if you really want to throw, and also want to do everything yourself:
print(s == null ? (throw "Null Bad!") : s.toUpperCase());
.
All in all, you need to promote to non-null
. There are lots of ways to do that.
CodePudding user response:
You stated the issue yourself, because it could be a null value you can't make it upper case because you can't make null upper case.