Dart 生成器函数 (yield / yield*)
Dart Generator Functions (yield / yield*)
我想了解生成器函数在 dart/flutter 中的工作原理。
flutter 团队 Generator Functions - Flutter in Focus 有一段视频,他们在其中讨论了以下示例。
Iterable<int> getRange(int start, int finish) sync* {
if (start <= finish) {
yield start;
print('start: $start');
for (final val in getRange(start+1, finish)) {
yield val;
print('val: $val');
}
}
}
只是没有打印线。
我像这样在 main 中调用了那个函数
void main() async {
getRange(0, 3).forEach(print);
}
得到以下结果:
0
start: 0
1
val: 1
start: 1
2
val: 2
val: 2
start: 2
3
val: 3
val: 3
val: 3
start: 3
我不明白输出结果的部分来自
1
val: 1
start: 1
为什么start: 1
在val: 1
之后。我不知何故不明白递归与收益率的结合是如何工作的。还有当 yield val;
被读取时会发生什么。
代码写得不好的一个很好的例子,做奇怪的事情,很难理解,因为代码一开始就写得很糟糕。为了使调试更容易,我将 start
变量添加到 print
语句中。还从您的 main()
中删除了 async
,因为这里没有 运行 异步:
Iterable<int> getRange(int start, int finish) sync* {
if (start <= finish) {
yield start;
print('(start = $start) start: $start');
for (final val in getRange(start + 1, finish)) {
yield val;
print('(start = $start) val: $val');
}
}
}
void main() {
getRange(0, 3).forEach(print);
}
输出:
0
(start = 0) start: 0
1
(start = 0) val: 1
(start = 1) start: 1
2
(start = 0) val: 2
(start = 1) val: 2
(start = 2) start: 2
3
(start = 0) val: 3
(start = 1) val: 3
(start = 2) val: 3
(start = 3) start: 3
所以你现在问的部分是:
1
(start = 0) val: 1
(start = 1) start: 1
您程序中的一个重要细节是您在 yield
之前 print()
。因此,当您执行 yield 1
时,该值将作为第一件事移动到 main()
中的 print
语句。然后您可以看到您的 for-loop 将在请求下一个值之前执行 val
打印,这将使 start = 1
循环继续。
sync*
方法中的 yield
表示方法传递值并停止执行该方法,直到请求新值。
我想了解生成器函数在 dart/flutter 中的工作原理。
flutter 团队 Generator Functions - Flutter in Focus 有一段视频,他们在其中讨论了以下示例。
Iterable<int> getRange(int start, int finish) sync* {
if (start <= finish) {
yield start;
print('start: $start');
for (final val in getRange(start+1, finish)) {
yield val;
print('val: $val');
}
}
}
只是没有打印线。
我像这样在 main 中调用了那个函数
void main() async {
getRange(0, 3).forEach(print);
}
得到以下结果:
0
start: 0
1
val: 1
start: 1
2
val: 2
val: 2
start: 2
3
val: 3
val: 3
val: 3
start: 3
我不明白输出结果的部分来自
1
val: 1
start: 1
为什么start: 1
在val: 1
之后。我不知何故不明白递归与收益率的结合是如何工作的。还有当 yield val;
被读取时会发生什么。
代码写得不好的一个很好的例子,做奇怪的事情,很难理解,因为代码一开始就写得很糟糕。为了使调试更容易,我将 start
变量添加到 print
语句中。还从您的 main()
中删除了 async
,因为这里没有 运行 异步:
Iterable<int> getRange(int start, int finish) sync* {
if (start <= finish) {
yield start;
print('(start = $start) start: $start');
for (final val in getRange(start + 1, finish)) {
yield val;
print('(start = $start) val: $val');
}
}
}
void main() {
getRange(0, 3).forEach(print);
}
输出:
0
(start = 0) start: 0
1
(start = 0) val: 1
(start = 1) start: 1
2
(start = 0) val: 2
(start = 1) val: 2
(start = 2) start: 2
3
(start = 0) val: 3
(start = 1) val: 3
(start = 2) val: 3
(start = 3) start: 3
所以你现在问的部分是:
1
(start = 0) val: 1
(start = 1) start: 1
您程序中的一个重要细节是您在 yield
之前 print()
。因此,当您执行 yield 1
时,该值将作为第一件事移动到 main()
中的 print
语句。然后您可以看到您的 for-loop 将在请求下一个值之前执行 val
打印,这将使 start = 1
循环继续。
sync*
方法中的 yield
表示方法传递值并停止执行该方法,直到请求新值。