I have:
Future<bool> foo() async => true;
This is allowed:
Future<void> bar() {
return foo(); // Works
}
but this is not:
Future<void> baz() async {
return foo(); // Error
}
In both bar and baz I'm returning a Future<bool>, but why first works but second fails?
Note: This question isn't about HOW to make it work but rather WHY one works and the other doesn't.
CodePudding user response:
Dart has special rules for void returning functions: You are not allowed to return a value because it's declared as not returning any value, so actually trying to return a value is probably a mistake.
The same happens without Future:
void qux() {
return true; // Error, can't return value from void function
}
gives the error
A value of type 'bool' can't be returned from the function 'qux' because it has a return type of 'void'.
You are allowed to have return e; statements, but only if the type of e is void, Null or dynamic. (And you shouldn't even do that, those are just allowed in order to make existing code work.)
(A => e body is always allowed, because people like to use it as a shorthand for just { e; }, mainly because the formatter keeps it on one line. I still recommend using { e; } as body of a void function.)
Generalizing that to async functions with void future return types,
you are not allowed to return an actual value from Future<void> ... async function. So, the only things you are allowed to return are void, dynamic, Null, Future<void>, Future<dynamic>, and Future<Null>.
A Future<bool> is neither of those.
What you should write instead is:
Future<void> baz() async {
await foo();
}
CodePudding user response:
As I have observed when I am running the same code
Future<bool> foo() async => true;
Future<void> bar() {
return foo(); // Works
}
Future<void> baz() async {
// return foo(); // Error
}
void main() {
print("direct =====${foo()}");
print("bar==========${bar()}");
print("bazz========${baz()}");
}
The response is
direct =====Instance of '_Future<bool>'
bar==========Instance of '_Future<bool>'
bazz========Instance of '_Future<void>'
this signifies that when the async keyword is not present it takes the return type of the returning value.
But of the bazz function it gives a quick fix to make the function
Future<Future<bool>>
so when async is added the function return type is taken as the main type
CodePudding user response:
Future<bool> foo() async => true;
First Case
Future<void> bar() {
return foo(); // Works
}
For the code above, the return of Future<void> bar() can return foo(), because the bar() not return directly the value of foo(), so the bar() can deal with foo() without no problem.
But, in the second case:
Future<void> baz() async {
return foo(); // Error
}
The code above is return directly the generic type of foo() because the function of baz() include async tag, so it will be trouble with the baz() as Future<void>, which is we know that foo() as Future<bool>
