题目
实现支持惰性求值的无限斐波那契数列生成器
信息
- 类型:问答
- 难度:⭐⭐
考点
枚举器(Enumerator), 惰性求值(Lazy Evaluation), 块(Block)和 yield
快速回答
实现步骤:
- 使用
Enumerator.new创建枚举器 - 通过
yield在循环中逐个生成斐波那契数 - 利用
lazy方法实现惰性求值 - 结合
take获取有限结果避免无限循环
问题背景
在 Ruby 中处理无限序列时,直接计算所有值会导致程序崩溃。惰性求值技术允许我们按需生成数据,这对处理大数据流或无限序列至关重要。
核心实现代码
# 创建无限斐波那契数列生成器
def infinite_fibonacci
Enumerator.new do |yielder|
a, b = 0, 1
loop do
yielder << a
a, b = b, a + b
end
end.lazy
end
# 使用示例:获取前10个斐波那契数
result = infinite_fibonacci.take(10).to_a
puts result.inspect #=> [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]原理说明
- 枚举器 (Enumerator):封装了迭代逻辑的对象,通过
yielder << value按需生成值 - 惰性求值:
.lazy方法将普通枚举器转为惰性枚举器,使map/select等操作延迟执行 - 避免无限循环:
take(n)从惰性枚举器中安全获取有限元素
最佳实践
- 优先使用
Enumerator而非数组处理潜在无限序列 - 对大数据集使用惰性枚举器减少内存占用
- 复杂操作链式调用示例:
infinite_fibonacci.select(&:even?).take(5).force
常见错误
- 忘记添加
.lazy导致立即求值引发无限循环 - 在枚举器外部修改迭代状态(应保持无状态)
- 误用
return代替yielder传递值
扩展知识
- 自定义惰性方法:通过继承
Enumerator::Lazy实现新惰性操作 - 性能对比:处理 1000 万数据时,惰性枚举器内存占用稳定在 1MB,而数组需要 400MB+
- 应用场景:日志流处理、大数据分页、数学无限序列