Home > OS >  Avoid duplication of null type checking in Dart
Avoid duplication of null type checking in Dart

Time:05-29

My current goal is to remove this code duplication:

final int? myNullableInt = 10;

/// Everywhere I need to do this null verification:
if (myNullableInt == null) return null;

return someOtherMethodThatReceivesANonNullableInt(myNullableInt);

I want to convert to something like we have in Kotlin:

final int? myNullableInt = 10;

return myNullableInt?.apply((myInt) => someOtherMethodThatReceivesANonNullableInt(myInt));

I did it:

extension ApplyIfNotNull on Object? {
  T? apply<T extends Object?>(Object? obj, T? Function(Object) fn) {
    if (obj == null) return null;
    return fn(obj);
  }
}

But this gives me a static error:

The argument type 'Object' can't be assigned to the parameter type 'int'.

Note: this should work with all types, e.g ints, Strings, double and MyOwnClassTypes.

There's something I can do? or am I missing something?

CodePudding user response:

extension ApplyIfNotNull on Object? {
  T? apply<T extends Object?>(Object? obj, T? Function(Object) fn) {
    if (obj == null) return null;
    return fn(obj);
  }
}

That doesn't work because it declares that the callback be capable of accepting any Object argument, but you're presumably trying to use it with a function that accepts only an int argument. It's also unclear why you've made an extension method since it doesn't involve the receiver (this) at all.

You need to make your function generic on the callback's argument type as well:

R? applyIfNotNull<R, T>(T? obj, R Function(T) f) =>
    (obj == null) ? null : f(obj);

(That's the same as what I suggested in https://github.com/dart-lang/language/issues/360#issuecomment-502423488 but with the arguments reversed.)

Or, as an extension method, so that it can work on this instead of having the extra obj argument:

extension ApplyIfNotNull<T> on T? {
  R? apply<R>(R Function(T) f) {
    // Local variable to allow automatic type promotion.  Also see:
    // <https://github.com/dart-lang/language/issues/1397>
    var self = this;
    return (self == null) ? null : f(self);
  }
}

Also see https://github.com/dart-lang/language/issues/360 for the existing language feature request and for some other suggested workarounds in the meantime.

CodePudding user response:

This is obviously quite close to what you do, and not really what you are asking for, but I'm not sure there is a better way. It saves a few characters:

return myNullableInt == null? null : myFunc(myNullableInt)

It's a bit less bloated (almost even than the Kotlin version), but not as "functional"...

  • Related