Ricardo Vieira
Ricardo Vieira

Reputation: 1818

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,

Upvotes: 38

Views: 16203

Answers (12)

Shimul Ahmed
Shimul Ahmed

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

Alessandro Mulloni
Alessandro Mulloni

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

sourav pandit
sourav pandit

Reputation: 9125

You can simply use this package kotlin_flavor: https://pub.dev/packages/kotlin_flavor/install

Upvotes: 0

kururu
kururu

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

user3612643
user3612643

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

Hossein Khoujani
Hossein Khoujani

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

lrn
lrn

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

R&#233;mi Rousselet
R&#233;mi Rousselet

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

YusukeIwaki
YusukeIwaki

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

Shababb Karim
Shababb Karim

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

boformer
boformer

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

G&#252;nter Z&#246;chbauer
G&#252;nter Z&#246;chbauer

Reputation: 657691

I guess a closure does what you want

class Foo {
  var x = 42;
  void bar() {
    () {
      print(x);
      doStuff();
      doABitMoreStuff();
      logStuff();
    }();
  }
}

Upvotes: -1

Related Questions