Ruby枚举器如何终止迭代?

问题描述 投票:2回答:2

[朋友,请提供有关以下解释的帮助:在下面的Ruby代码中,什么条件限制了循环的作用?它应该是一个无限循环,但是,它如何终止?

# Ruby code
fib = Enumerator.new do |y|
  a = b = 1
  loop do
    y << a
    a, b = b, a + b
  end
end

p fib.take(10) # => [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

您的贡献将受到高度赞赏。

ruby enumerable enumerator take
2个回答
3
投票

((来源:https://rossta.net/blog/infinite-sequences-in-ruby.html

您已实现功能fib的方式使其“懒惰”。这意味着Ruby在绝对必要之前不会尝试计算fib中的值。

最后一行的take方法是这里的关键。

p fib.take(10) 

[基本上,Ruby说:“我将评估fib的前10个值,并假装其余的值不存在,因为我还必须不使用它们。”

换句话说,虽然fib函数确实是无限的,但您只要求输入前10个值,所以您只获得了前10个值。

如果您尝试过类似的操作:

p fib.to_a

您的程序会卡住。为什么?因为to_a(到数组)方法想要尝试获取[[all fib的值,而不仅仅是其中的几个。显然,您无法获得无限列表的all值。

更多信息:

https://medium.com/background-thread/what-is-lazy-evaluation-programming-word-of-the-day-8a6f4410053f

https://github.com/juinc/tilap/issues/9


0
投票
枚举器就像Pez® dispenser,每次按下分配器顶部时,都会弹出薄荷糖。分配器的枚举器版本将不容纳糖果的供应,但是会根据需要一次制造一个糖果,可能能够生产无限数量的糖果。

枚举器的一种类型与对象的基础集合相关联。这是两个与数组绑定的对象。

enum = [1,2,3].each #=> #<Enumerator: [1, 2, 3]:each> enum.next #=> 1 enum.next #=> 2 enum.next #=> 3 enum.next #=> StopIteration (iteration reached an end)

 

enum = [1,2,3].cycle #=> #<Enumerator: [1, 2, 3]:cycle> enum.next #=> 1 enum.next #=> 2 enum.next #=> 3 enum.next #=> 1 enum.next #=> 2 ... ad infinitum enum.first(8) #=> [1, 2, 3, 1, 2, 3, 1, 2]

在第一个示例中,在引发StopIteration异常之前,枚举器仅生成有限数量的对象。在第二个示例中,可以生成任意数量的对象,但只能生成

on demand。例如,first(8)指示enum生成并传递给自身的8对象。 enum不是lazy;所有人都渴望遵守,但除非得到指示,否则不会制造和分配糖果或其他东西。

另一种类型的枚举器根据它所固有的一组规则生成对象,这些规则不与基础对象绑定。这些枚举器通常能够生成无限数量的对象。生成斐波那契数的枚举器就是这种枚举器的一个示例。这不是一个不会终止的循环。它是一台能够按需生产任意数量但每次只能生产一个物体的机器。
© www.soinside.com 2019 - 2024. All rights reserved.