参考文档:dart.cn/guides/lang…
当你需要延迟地生成一连串的值时,可以考虑使用生成器函数。Dart内置支持两种形式的生成器方法:
- 同步生成器:返回一个
Iterable对象。 - 异步生成器:返回一个
Stream对象。
使用sync*将一个函数标记为同步生成器,并返回Iterable对象,
Iterable<int> naturalsTo(int n) sync* {
int k = 0;
while (k < n) yield k++;
}
使用async*标记函数为异步生成器,返回一个Stream对象
Stream<int> asynchronousNaturalsTo(int n) async* {
int k = 0;
while (k < n) yield k++;
}
yield有什么用呢🤔?
根据stackoverflow的回答, yield作用同return,都是返回一个值,区别在于yield并不会退出函数。
如上面示例中,yield会返回k的值,但是不退出naturalsTo函数,直到while循环结束才退出naturalsTo函数
Demos
- 使用同步生成器生成range函数,用于for循环。
Iterable<int> range(int end, {int step = 1, int start = 0}) sync* {
if (step == 0) throw Exception('Step cannot be 0');
if ((step > 0 && start < end) || (step < 0 && start > end)) {
yield start;
yield* range(end, step: step, start: start + step);
}
}
void main() {
// 递增间隔1(默认)
for (var value in range(5)) print(value); // [0, 1, 2, 3, 4]
// 递增间隔2
for (var value in range(5, step: 2)) print(value); // [0, 2, 4]
// 递增间隔5
for (var value in range(5, step: 5)) print(value); // [0]
// 递减间隔1
for (var value in range(-1, start: 4, step: -1))
print(value); // [4, 3, 2, 1, 0]
// 递减间隔2
for (var value in range(-1, start: 4, step: -2)) print(value); // [4, 2, 0]
// 递减间隔5
for (var value in range(-1, start: 4, step: -5)) print(value); // [4]
}
- 生成器语法糖
// 使用语法糖得到一个迭代器
var iterator = [for (var i = 0; i < 5; i++) i];
for (var value in iterator) print(value);
关于Stream
有个表格很清楚的表达了意思, 后续再讲一讲使用吧。
| int | 单值 | 多值 |
|---|---|---|
| 同步 | int | Iterator<int> |
| 异步 | Future<int> | Stream<int> |