Reputation: 1818
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,
Upvotes: 38
Views: 16203
Reputation: 1
I have implemented this like following pattern:
extension Let<T> on T {
void let(void Function(T) block) { return block(this); }
}
class Test{
int? curValue;
void setValue() { curValue = 33; }
void workValue() {
curValue?.let((value){
int x = value;
print(value);
});
}
}
Upvotes: 0
Reputation: 1269
You can achieve the same behaviour with an extension. Here is one extension that behaves like Kotlin's let and takes one function to be performed on the non-null object.
extension NotNull<T extends Object> on T {
void ifNotNull(Function(T) action) {
action(this);
}
}
You can then use it as follows:
final int? value = 42;
value?.ifNotNull((v) => print(v)); // Prints "42"
or
final int? value;
value?.ifNotNull((v) => print(v)); // Prints nothing
Upvotes: 0
Reputation: 9125
You can simply use this package kotlin_flavor: https://pub.dev/packages/kotlin_flavor/install
Upvotes: 0
Reputation: 100
i implemented let function with extension function like this:
extension KotlinLet on Object?{
void let(Function callback ){
if (this != null) {
callback();
}
}
Object? also(){
if (this != null) {
return this;
}
}
}
Upvotes: 0
Reputation: 5772
With the new Dart extension functions, we can define:
extension ObjectExt<T> on T {
R let<R>(R Function(T that) op) => op(this);
}
This will allow to write x.let(f)
instead of f(x)
.
Upvotes: 32
Reputation: 39
Using this extension:
extension Ext on Object? {
void ifNotNull(Function() action) {
if(this != null){
action();
}
}
}
You can achieve something similar:
object.ifNotNull(() => {
// safe code
});
Upvotes: 1
Reputation: 71743
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.
Upvotes: 2
Reputation: 277367
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) {
})
Upvotes: 13
Reputation: 59
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
Upvotes: 5
Reputation: 3733
Even though Dart doesn't have the let
like behavior as of Kotlin but we can certainly emulate it with concise and readable code. Maybe something like this:
void main() {
String str = null;
str?.isEmpty ?? Function.apply(() {
print("Hey there you cheeky null valued variable");
}, []);
}
Upvotes: 0
Reputation: 30103
There is no direct equivalent, because there is no need for it in Dart. Dart is a lot more like Java and you often end up with similar solutions.
There is almost no syntactic sugar in Dart. It's supposed to be easy to learn.
Also, Dart does not enforce strict null checks, all variables are nullable, and the language is single-threaded. That's why there is no need for let
. Use if
instead:
if(variable != null) {
doStuff();
doABitMoreStuff();
logStuff();
}
Upvotes: -2
Reputation: 657691
I guess a closure does what you want
class Foo {
var x = 42;
void bar() {
() {
print(x);
doStuff();
doABitMoreStuff();
logStuff();
}();
}
}
Upvotes: -1