What is Dart's equivalent to Kotlin's let?
Recently I've been delving into Flutter's ecosystem and Dart has proven itself a neat and simple language.
Currently, I am looking for a best practice to run methods if an optional variable is not null.
In other words, I am looking for something in Dart that is like Kotlin's let operator :
variable?.let {
doStuff();
doABitMoreStuff();
logStuff();
}
Anyone got any ideas or best practices around this?
I've looked into Dart's documentation and have found nothing that would fit my requirements.
King regards,
Solution 1:
With the new Dart extension functions, we can define:
extension ObjectExt<T> on T {
R let<R>(R Function(T that) op) => op(this as T);
}
This will allow to write x.let(f)
instead of f(x)
.
Solution 2:
Dart's equivalent would be a null-aware cascade operator: The Dart approach would be a to use a null-aware cascade:
SomeType? variable = ...
variable
?..doStuff()
..doABitMoreStuff()
..logStuff();
The null-aware cascade works like the normal cascade, except that if the receiver value is null
, it does nothing.
You could make your own using a static function though:
typedef T LetCallback<T>(T value);
T let<T>(T value, LetCallback<T> cb) {
if (value != null) {
return cb(value);
}
}
Then used like that:
let<MyClass>(foo, (it) {
})
Solution 3:
We can do it with Dart 2.6 or later.
extension ScopeFunctionsForObject<T extends Object> on T {
ReturnType let<ReturnType>(ReturnType operation_for(T self)) {
return operation_for(this);
}
}
usage: https://github.com/YusukeIwaki/dart-kotlin_flavor#let
Solution 4:
The difference between x?.let{ }
and if (x != null) { }
in Kotlin is that the former promotes x
to be non-nullable. Since Kotlin has non-nullable types, it prevents you from needing to write x!!
to assert the non-nullability inside the block.
Dart doesn't have non-nullable types (yet), so that distinction isn't important in Dart.
Just use if (x != null) { ... }
.
If Dart gets non-nullable types, you can be assured that the null
check in the condition will also promote x
to non-nullable inside the block (if x
is a local variable, is not mutated inside the block, other restrictions may apply).
(EDIT: Dart now has nullable types, and x != null
promotes x
to non-null
.)
From your other comments, it sounds like you might be wanting the Kotlin behavior of x?.run { ... }
instead, which binds this
to x
inside the lambda block. There is no corresponding feature in Dart. You cannot override this
, it's always bound to the the object that the current method was called on, even inside nested closures which captures the value of this
just as they capture other variables.
Solution 5:
I guess a closure does what you want
class Foo {
var x = 42;
void bar() {
() {
print(x);
doStuff();
doABitMoreStuff();
logStuff();
}();
}
}