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.
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"...