yield
关键字在Dart中实际上做了什么?
yield
向周围async*
函数的输出流添加一个值。它类似于return
,但不会终止函数。
请参阅 https://dart.dev/guides/language/language-tour#generators
Stream asynchronousNaturalsTo(n) async* {
int k = 0;
while (k < n) yield k++;
}
当 yield 语句执行时,它会将其表达式的计算结果添加到流中。它不一定暂停(尽管在当前的实现中它确实如此)。
接受答案的链接已断开,这是关于async* sync* yield* yield
的官方链接。
如果您对其他语言有一些经验,您可能会停留在这些关键字上。以下是一些克服关键字的提示。
-
async* sync* yield* yield
称为生成器函数。您可能主要在Bloc 模式中使用它们。 -
async*
也是一个async
,你可以像往常一样使用异步。 -
sync*
不能用作sync
,您将收到注意到"修改器同步后必须跟着星号">的错误。 -
yield
和yield*
只能与生成器函数一起使用(async*
sync*
)。
并且有四种组合。
async* yield
将返回一个Stream<dynamic>
。
Stream<int> runToMax(int n) async* {
int i = 0;
while (i < n) {
yield i;
i++;
await Future.delayed(Duration(seconds: 300));
}
}
async* yield*
将调用一个函数并返回Stream<dynamic>
。
Stream<int> countDownFrom(int n) async* {
if (n > 0) {
yield n;
yield* countDownFrom(n - 1);
}
}
sync* yield
将返回一个Iterable<dynamic>
。
Iterable<int> genIterates(int max) sync* {
var i = 0;
while (i < max) {
yield i;
i++;
}
}
sync* yield*
将调用一个函数并返回Iterable<dynamic>
。
Iterable<int> countDownFrom(int n) sync* {
if (n > 0) {
yield n;
yield* countDownFrom(n - 1);
}
}
如果有任何错误,请发表评论以更正答案。
我认为 yield* 的正确答案是委托给另一个生成器而不是调用函数。 yield* 只是委托给另一台发电机,这意味着电流发电机停止,另一台发电机承担工作,直到它停止生产。在此停止生成值后,主生成器恢复生成自己的值。
感谢@András Szepesházi鼓励我发布此评论作为答案,希望对您有所帮助。
yield
语句只能在生成器的函数中使用。
生成器的功能以自然的方式生成数据项(计算、从外部接收、预定义值等)。
当下一个数据项准备就绪时,yield
语句将此项发送到数据序列中,这本质上是函数的生成结果。
数据序列可以是同步的,也可以是异步的。
在Dart语言中,同步数据序列表示Iterable
的实例。
异步数据序列表示Stream
的实例。
P.S.
生成器函数可以无限期地生成数据项,直到函数返回。
但与普通函数不同的是,结果(数据序列)将在函数调用后立即返回,并且可以立即使用。
在这种情况下,只有当生成器功能终止(成功或失败)时,才能到达数据序列的末尾。