Home > Software engineering >  Can you pass an extension method as a function argument in Dart?
Can you pass an extension method as a function argument in Dart?

Time:11-16

Is there a way to pass an extension method as a function argument?

I'd like to pass an extension method to a .map method like a static function if it's possible.

Something like this:

extension Add10 on int {
  int add10() {
    return this   10;
  }
}

int add100(int x) => x   100;

// I'd like to do something like this
[1, 2, 3, 3, 5].map(Add10.add10);

// Like I could do with a regular function
[1, 2, 3, 4, 5].map(add100);

// instead of
[1, 2, 3, 4, 5].map(x => x.add10());

Is this possible?

In other words, can an extension method on int that returns an int satisfy the signature

int Function(int)

like my add100 function can?

Or are extension methods always treated more like a class that must wrap the value before making the call?

CodePudding user response:

Technically you can use a static function inside extension

[1, 2, 3, 3, 5].map(**Add10.add10**);

So you can change your extension method(and function signature)

extension Add10 on int {
  static int add10(int i) {
    return i   10;
  }
}

But I don't think it's a good idea

CodePudding user response:

No, not like that.

An extension method is like an instance method in this regard. You can't extract an instance method from int int to a function, pass it somewhere else, and then call that method on other integers.

Just like an instance method, you need to do:

[1, 2, 3, 3, 5].map((x) => x.add10())

That's one situation where extension methods are less usable than the static helper function they're intended to replace. As @eugene-kuzmenko points out, you can make the extension method a static function instead (not necessarily inside an extension declaration), and then you can tear it off an pass it as an argument, because then it's not inherently tied to a single receiver, but it takes the number to act on as an argument, like Iterable.map expects.

If you are going to turn the result of the map into a List anyway, I'd probably just use a literal:

var numbers = [1, 2, 3, 3, 4];
var newNumbers = [for (var x in numbers) x.add10()];

It looks slightly more cumbersome, but in practice I find it much more convenient to not have to write functions literals (and it also works with asynchronous operations then).

  • Related