TypeScript - 迭代器和生成器
你好啊,未来的编程超级巨星!欢迎来到TypeScript的精彩世界,我们将一起探索迭代器和生成器的神奇领域。如果这些术语现在对你来说听起来像是外星技术,别担心——在本教程结束时,你将能够像专业人士一样熟练地使用它们!那么,让我们卷起袖子,开始吧!
迭代器
想象一下你有一个装满各种玩具的玩具箱。迭代器就像一根魔法棒,它可以帮助你一个接一个地穿过每个玩具,而不需要把整个箱子倒在地上。酷吧?让我们看看在TypeScript中这是如何工作的!
什么是迭代器?
迭代器是一个定义了next()
方法的对象,该方法返回序列中的下一个项目。当没有更多项目时,它返回一个特殊值来指示序列已结束。
让我们创建我们的第一个迭代器:
function createNumberIterator() {
let n = 0;
return {
next: function() {
n += 1;
if (n <= 5) {
return { value: n, done: false };
}
return { value: undefined, done: true };
}
};
}
const numberIterator = createNumberIterator();
console.log(numberIterator.next()); // { value: 1, done: false }
console.log(numberIterator.next()); // { value: 2, done: false }
console.log(numberIterator.next()); // { value: 3, done: false }
console.log(numberIterator.next()); // { value: 4, done: false }
console.log(numberIterator.next()); // { value: 5, done: false }
console.log(numberIterator.next()); // { value: undefined, done: true }
在这个例子中,我们创建了一个从1数到5的迭代器。每次我们调用next()
时,它都会给我们下一个数字。当它达到5时,通过返回{ value: undefined, done: true }
来告诉我们它已经完成了。
使用迭代器和for...of循环
TypeScript使得使用迭代器和for...of
循环更加容易。让我们看看如何操作:
function* numberGenerator() {
yield 1;
yield 2;
yield 3;
yield 4;
yield 5;
}
for (const num of numberGenerator()) {
console.log(num);
}
// 输出:
// 1
// 2
// 3
// 4
// 5
这个for...of
循环会自动使用迭代器来遍历所有值。就像有一个机器人助手为你从箱子里拿起每个玩具!
生成器
现在,让我们来谈谈生成器。如果迭代器是魔法棒,那么生成器就像是能够轻松创建这些魔法棒的巫师!
什么是生成器?
生成器是一种特殊的函数,可以被暂停和恢复,允许它随时间生成一系列值,而不是一次性计算并返回它们组成的数组。
让我们创建我们的第一个生成器:
function* countToFive() {
yield 1;
yield 2;
yield 3;
yield 4;
yield 5;
}
const generator = countToFive();
console.log(generator.next().value); // 1
console.log(generator.next().value); // 2
console.log(generator.next().value); // 3
console.log(generator.next().value); // 4
console.log(generator.next().value); // 5
console.log(generator.next().value); // undefined
在这个例子中,countToFive
是一个生成器函数。yield
关键字就像是在说:“这是下一个值,但让我们在这个之后休息一下。”每次我们调用next()
,函数就会运行直到遇到yield
,给我们那个值,然后暂停。
生成器和循环
当生成器与循环结合时,它们变得更加强大。让我们看一个例子:
function* evenNumbersUnder20() {
for (let i = 2; i < 20; i += 2) {
yield i;
}
}
for (const num of evenNumbersUnder20()) {
console.log(num);
}
// 输出:
// 2
// 4
// 6
// 8
// 10
// 12
// 14
// 16
// 18
这个生成器生成了所有小于20的偶数。就像有一个智能玩具分发器,只分发特定类型的玩具!
迭代器和生成器的区别
现在我们已经看到了迭代器和生成器的实际应用,让我们分解一下它们的关键区别:
特性 | 迭代器 | 生成器 |
---|---|---|
定义 | 具有next()方法的对象 | 带有* 符号的函数 |
状态管理 | 手动 | 自动 |
创建难度 | 更复杂 | 更简单 |
暂停/恢复 | 不是内置的 | 使用yield 内置 |
内存效率 | 对于大型数据集可能更高效 | 对大型或无限序列极佳 |
迭代器就像是从零开始构建一个玩具机器人——你必须定义每一个小细节。另一方面,生成器就像得到一个预先构建好的机器人,你可以轻松定制。两者都有它们的位置和用途!
现实世界的例子
让我们用一个有趣的真实世界例子来结束我们的学习,它结合了我们所学的内容:
function* fibonacciGenerator() {
let a = 0, b = 1;
while (true) {
yield a;
[a, b] = [b, a + b];
}
}
const fib = fibonacciGenerator();
for (let i = 0; i < 10; i++) {
console.log(fib.next().value);
}
// 输出:
// 0
// 1
// 1
// 2
// 3
// 5
// 8
// 13
// 21
// 34
这个生成器创建的是著名的斐波那契数列——一个每个数字都是前两个数字之和的数学数列。就像一个永无止境的楼梯,每个台阶都是由前两个台阶建造的!
就这样,我的编程学徒们!我们已经穿越了迭代器和生成器的领域,看到了它们的相似之处和不同之处,甚至创造了一些我们自己的魔法。记住,熟能生巧,所以不要害怕尝试这些概念。谁知道你会用你新的迭代器和生成器能力创造出多么惊人的程序呢?快乐编程,愿你的代码总是第一次编译就成功!
Credits: Image by storyset