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

SyntaxDart

Syntax Problem Overview


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.

Syntax Solutions


Solution 1 - Syntax

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

Solution 2 - Syntax

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);
}

Solution 3 - Syntax

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

Solution 4 - Syntax

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. > > dart > 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;
}

Solution 5 - Syntax

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(),
));

Solution 6 - Syntax

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))

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionEthanView Question on Stackoverflow
Solution 1 - SyntaxZectbumoView Answer on Stackoverflow
Solution 2 - SyntaxCopsOnRoadView Answer on Stackoverflow
Solution 3 - Syntaxdiegod3vView Answer on Stackoverflow
Solution 4 - SyntaxHrishikesh KadamView Answer on Stackoverflow
Solution 5 - SyntaxPanayiotis HiripisView Answer on Stackoverflow
Solution 6 - SyntaxMarc_LView Answer on Stackoverflow