Ethan
Ethan

Reputation: 9768

What does it mean to pass `_` (i.e., underscore) as the sole parameter to a Dart language function?

I'm learning Dart and see the following idiom a lot:

someFuture.then((_) => someFunc());

I have also seen code like:

someOtherFuture.then(() => someOtherFunc());

Is there a functional difference between these two examples? A.k.a., What does passing _ as a parameter to a Dart function do?

This is particularly confusing given Dart's use of _ as a prefix for declaring private functions.

Upvotes: 66

Views: 15977

Answers (6)

CopsOnRoad
CopsOnRoad

Reputation: 267684

An underscore (_) is usually an indication that you will not be using this parameter within the block. This is just a neat way to write code.

Let's say I've a method with two parameters useful and useless and I'm not using useless in the code block:

void method(int useful, int useless) {
  print(useful);
}

Since useless variable won't be used, I should rather write the above code as:

void method(int useful, int _) { // 'useless' is replaced with '_'
  print(useful);
}

Upvotes: 8

Hrishikesh Kadam
Hrishikesh Kadam

Reputation: 37342

From the Dart Doc - PREFER using _, __, etc. for unused callback parameters.

Sometimes the type signature of a callback function requires a parameter, but the callback implementation doesn't use the parameter. In this case, it's idiomatic to name the unused parameter _. If the function has multiple unused parameters, use additional underscores to avoid name collisions: __, ___, etc.

futureOfVoid.then((_) {
  print('Operation complete.');
});

This guideline is only for functions that are both anonymous and local. These functions are usually used immediately in a context where it's clear what the unused parameter represents. In contrast, top-level functions and method declarations don't have that context, so their parameters must be named so that it's clear what each parameter is for, even if it isn't used.

Copy paste the following code in DartPad and hit Run -

void main() {
  
  Future.delayed(Duration(seconds: 1), () {
    print("No argument Anonymous function");
  });
  
  funcReturnsInteger().then((_) {
    print("Single argument Anonymous function " + 
    "stating not interested in using argument " +
    "but can be accessed like this -> $_");
  });
}

Future<int> funcReturnsInteger() async {
  return 100;
}

Upvotes: 5

Panayiotis Hiripis
Panayiotis Hiripis

Reputation: 700

Very common use, is when we need to push a new route with Navigator but the context variable in the builder is not going to be used:

// context is going to be used
Navigator.of(context).push(MaterialPageRoute(
  builder: (context) => NewPage(),
));


// context is NOT going to be used
Navigator.of(context).push(MaterialPageRoute(
  builder: (_) => NewPage(),
));

Upvotes: 1

MarcL
MarcL

Reputation: 3593

I think what people are confusing here is that many think the _ in

someFuture.then((_) => someFunc());

is a parameter provided to the callback function which is wrong, its actually a parameter passed back from the function that you can give a name that you want (except reserved keywords of course), in this case its an underscore to show that the parameter will not be used. otherwise, you could do something like in example given above:((response) => doSomethingWith(response))

Upvotes: 0

Zectbumo
Zectbumo

Reputation: 4471

It's a variable named _ typically because you plan to not use it and throw it away. For example you can use the name x or foo instead. The difference between (_) and () is simple in that one function takes an argument and the other doesn't.

DON’T use a leading underscore for identifiers that aren’t private.

Exception: An unused parameter can be named _, __, ___, etc. This happens in things like callbacks where you are passed a value but you don’t need to use it. Giving it a name that consists solely of underscores is the idiomatic way to indicate the value isn’t used.

https://dart.dev/guides/language/effective-dart/style

Upvotes: 81

diegod3v
diegod3v

Reputation: 674

That expression is similar to "callbacks" in node.js, the expression have relation to async task.

First remember that => expr expression is shorthand for {return *expr*}, now in someFuture.then((_) => someFunc()), someFuture is a variable of type Future, and this keeps your async task, with the .then method you tell what to do with your async task (once completed), and args in this method you put the callback ((response) => doSomethingWith(response)).

You learn more at Future-Based APIs and Functions in Dart. Thanks

Upvotes: 2

Related Questions