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 int
s, String
s, double
and MyOwnClassType
s.
Is there something I can do? or am I missing something?
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>
final 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.