面试题答案
一键面试- 生成器状态管理的一般原理:
- 暂停时保存状态:在Rust中,生成器是通过
async fn
语法糖来实现(在async
/await
背后使用了生成器概念)。当生成器执行到yield
语句时暂停,生成器的当前栈帧和局部变量等状态信息会被捕获并保存。Rust编译器会自动将生成器函数转换为一个状态机,这个状态机包含了生成器执行过程中的所有状态信息。生成器的局部变量、当前执行位置等都会成为状态机状态的一部分。 - 恢复时恢复状态:当生成器被恢复执行时(通常是通过调用生成器的
resume
方法,在async
/await
场景下,当await
点之后恢复执行),状态机从保存的状态中恢复,包括局部变量的值和执行位置。生成器从暂停的yield
语句之后继续执行。
- 暂停时保存状态:在Rust中,生成器是通过
- 斐波那契数列生成器状态处理示例:
- 斐波那契数列生成器需要保存前两个数(初始值通常为0和1)以便生成下一个数。可以定义一个结构体来管理生成器的状态。
struct FibonacciGenerator { a: u64, b: u64, } impl FibonacciGenerator { fn new() -> Self { FibonacciGenerator { a: 0, b: 1 } } } // 将生成器实现为迭代器 impl Iterator for FibonacciGenerator { type Item = u64; fn next(&mut self) -> Option<Self::Item> { let result = self.a; let new_b = self.a + self.b; self.a = self.b; self.b = new_b; Some(result) } }
- 在上述代码中,
FibonacciGenerator
结构体的a
和b
字段在每次调用next
(类似于yield
的效果)之间保存了生成斐波那契数列所需的状态。每次调用next
时,生成器计算并返回下一个斐波那契数,同时更新a
和b
的值,以便下次调用next
时继续生成序列。如果使用async
/await
风格实现生成器(更接近标准的生成器概念):
async fn fibonacci_generator() -> impl Stream<Item = u64> { let mut a = 0; let mut b = 1; loop { let result = a; let new_b = a + b; a = b; b = new_b; yield result; } }
- 这里
async fn
定义的生成器,a
和b
作为局部变量,在每次yield
暂停和恢复之间,它们的值会被状态机保存和恢复,从而保持生成斐波那契数列的连续性。