本文主要是介绍Dart【06】generator生成器函数,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
什么是生成器函数
Dart生成器函数 (generator)
可以渐进的返回一个值的序列。
Dart
内置了两种生成器函数的支持:
同步生成器(sync*
):返回一个Iterable
对象。
异步生成器(async*
):返回一个Stream
对象。
同步生成器
使用同步生成器修饰的函数返回的是迭代器Iterable
Iterable
主要使用iterator
的两个方法moveNext()
,current
,current
代表了当前元素,moveNext()
将迭代器推进到迭代的下一个元素。
用一段代码展示如何使用同步生成器:
Iterable<int> naturalsTo(int n) sync* {int k = 0;while (k < n) yield k++;
}
测试代码:
void main() {Iterable<int> sequence = naturalsTo(5);print("Starting...");for (int value in sequence) {print(value);}print("DONE");
}
输出如下:
Starting…
0
1
2
3
4
DONE
代码解读:
上面示例中的naturalsTo
函数就是使用同步生成器修饰的函数,首先在函数方法体花括号前加入sync*
关键字,然后使用yield
关键字进行值的返回。
上面的代码示例yield
关键字向迭代器序列依次添加了五个值。
看到这里你可能有点疑问,函数返回值不是return
吗?yield
是干嘛的?
yield和yield*
yield
的作用:
yield
向周围sync*
函数的迭代器中添加一个值。就像return
,但不会终止函数。
上面的代码示例yield
关键字向迭代器序列依次添加了五个值。
与yield
功能类似的还有一个关键字yield*
,yield*
只是一种简化写法。如果生成器是递归的,可以使用 yield*
来提高其性能。
用两段代码示例来展示yield*
是如何简化代码的:
这是一段没有使用yield*
的代码:
void main() {for (int i in numbersDownFrom(3)) {print('$i');}
}Iterable<int> numbersDownFrom(int n) sync* {if (n != 0) {yield n;for (var val in numbersDownFrom(n - 1)) {yield val;}}
}
输出如下:
3
2
1
for (var val in numbersDownFrom(n - 1)) {yield val;}
这段代码是函数的递归调用,代码流程完全是同步的,你可能要花上一点时间阅读一下代码,你就能理解这段代码做了什么事情。
接下来我们用yield*
来简化这段代码:
void main() {for (int i in numbersDownFrom(3)) {print('$i');}
}Iterable<int> numbersDownFrom(int n) sync* {if (n != 0) {yield n;yield* numbersDownFrom(n - 1);}
}
输出如下:
3
2
1
两段代码的作用完全一样,你应该已经理解yield*
的作用了,就是对For
循环+yield
的一种简化。
异步生成器
异步生成器async*
在原理上和同步生成器完全一样,都是渐进的返回一个值的序列,唯一区别就是同步生成器返回的是迭代器。异步声明器返回的是Stream
。
关于Stream
的详细介绍参考作者之前的文章。
用一段与上面sync*
使用方式一样的代码来为你展示如何使用异步生成器async*
Stream<int> naturalsTo(int n) async* {int k = 0;while (k < n) yield k++;
}
测试代码:
void main() async{Stream<int> sequence = naturalsTo(5);print("Starting...");await for (int value in sequence) {print(value);}print("DONE");
}
输出如下:
Starting…
0
1
2
3
4
DONE
async*
与sync*
工作原理完全一致,如果你对async
和await for
有疑问,参考作者之前的文章。
sync,sync*,async,async*
文章看到这里对异步的全部介绍已经结束了,用一张图片来帮助你记忆sync,sync*,async,async*
的区别。
这篇关于Dart【06】generator生成器函数的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!