Home > database >  Why I can't call "toUpperCase()" on a "String?" variable?
Why I can't call "toUpperCase()" on a "String?" variable?

Time:06-14

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());. The s! throws if s is null, and otherwise it has type String, so you can call toUpperCase on it. That simulates the pre-null-safety behavior of checking for null, and throwing if you find it. The ! here is called the "null check operator".
  • print((as as String).toUpperCase());. Same as s!, just with more steps.

Non-throwing:

  • print(s?.toUpperCase());. The s?.toUpperCase() calls toUpperCase on s only if s is not null. If s is null, it doesn't call anything, and the result is again null. Luckily print accepts null 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 as s?.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 if s 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.

  •  Tags:  
  • dart
  • Related