Future<void> async 与 Dart 中的简单 void async
Posted
技术标签:
【中文标题】Future<void> async 与 Dart 中的简单 void async【英文标题】:Future<void> async vs simply void async in Dart 【发布时间】:2021-05-26 08:50:48 【问题描述】:在 Dart 中,
和说有什么区别
Future<void> doStuff() async ...
和
void doStuff() async ...
我知道 Future
请注意,这两个函数都使用异步。问题不是“异步函数和非异步函数有什么区别?”或者“您能简要介绍一下 Dart 中的异步编程吗?”
我知道已经有一个几乎相同的问题,但是如果您仔细查看答案,您会发现实际上没有人以明确的方式回答这个问题 - 有什么区别?有什么区别吗?没有区别吗?
详细来说,考虑以下两个函数:
// notice there is no warning about not returning anything
Future<void> futureVoid() async
await Future.delayed(Duration(seconds: 2), ()
var time = DateTime.now().toString();
print('$time : delay elapsed');
);
void nonFutureVoid() async
await Future.delayed(Duration(seconds: 2), ()
var time = DateTime.now().toString();
print('$time : delay elapsed');
);
然后用 onPressed() 函数为的按钮测试它们:
onPressed: () async
await nonFutureVoid(); // notce that this await *DOES* delay execution of the proceeding lines.
var time = DateTime.now().toString();
print('$time : <-- executed after await statement');
日志结果:
flutter: 2021-02-23 21:46:07.436496 : delay elapsed
flutter: 2021-02-23 21:46:07.437278 : <-- executed after await statement
如您所见,它们的行为方式完全相同——等待简单的 void 异步版本。那么区别是什么呢?谢谢。
【问题讨论】:
我很确定这是一个与我实际回答的问题相同的问题:What's the difference between returning void vs returning Future<void>? 好吧,我不知道有这个问题,谢谢......虽然实际差异在 cmets 中被散列出来并且似乎没有定论,但这并不是最大的。 你不能等待虚空,你可以等待未来void
函数完成。时期。这没有什么不确定的。
我预计评论会被删除。 :D
【参考方案1】:
void
函数表示该函数不返回任何内容,这意味着您不能对该函数的结果采取行动(也不能await
对其结果进行操作)。
同时,Future<void>
函数返回一个 Future 对象(其值为 void
)。如果您没有return
语句,则会出现missing_return
警告(仍然可以编译)。您仍然可以通过等待它来处理该结果,但不能实际使用该值,因为它是 void
。
虽然看起来无论您使用什么都可以,但我认为最好为每个 async
函数使用 Future
以实现类型安全和更好的维护。
【讨论】:
Futurevoid
函数不能等待,因为它表明它不会返回任何东西
感谢您的努力。我稍微修改了这个问题。【参考方案2】:
通过您的编辑,您的问题更有意义。您的问题实际上是关于原则与实践。
原则上,返回void
的函数与返回Future<void>
的函数不同。一个在概念上代表不返回任何东西的东西,另一个代表可以在完成时触发回调的异步计算。
原则上,您应该从不尝试使用从void
函数返回的值。这没有意义。如果您针对执行 await nonFutureVoid();
的代码运行 Dart 分析器,如果启用了 await_only_futures
lint,则会收到警告。
在实践中,有种情况,尝试使用 void
返回值碰巧不会产生错误。这些是语言中的怪癖(或实现中的错误); 您不应依赖它们。 (Dart 最初没有void
返回类型。后来添加时,它并没有实现为“无值”,而是表示“不允许使用的值”。见@ 987654322@。通常情况下,细微的差别并不重要。)
能够做到await nonFutureVoid();
是bug1,而且似乎该错误现已修复:await nonFutureVoid();
是一个错误,如果你使用Dart 2.12 或更高版本,并启用 null 安全性和随之而来的更严格的类型检查。
您可以通过切换“Null Safety”按钮来观察 DartPad 的新旧行为:https://dartpad.dartlang.org/b0dae0d5a50e302d26d93f2db3fa6207
1 在 GitHub 上提交了很多问题,并有很多来回讨论,所以是的,这相当混乱。然而,大多数人似乎都同意允许await void
是不可取的。
【讨论】:
以上是关于Future<void> async 与 Dart 中的简单 void async的主要内容,如果未能解决你的问题,请参考以下文章
返回 void 与返回 Future<void> 有啥区别?
如何将 std::future<T> 转换为 std::future<void>?